[FFmpeg-devel] [PATCH v5 00/10] make QSV works with the Intel's oneVPL
The oneAPI Video Processing Library (oneVPL) is a single interface for encode, decode and video processing[1]. oneVPL is a successor to Intel(R) Media SDK, but removed obsolete features. Intel(R) Media SDK lifetime comes to an end now, new features for new Intel Gen platforms will be supported in oneVPL only[2]. It is recommended to use oneVPL for new work, even for currently available hardwares[3]. Hence, this patchset added a new option --enable-onevpl to bring the support for oneVPL in QSV. New features for oneVPL will be implemented in other patchset. --enble-libmfx option still works with Intel(R) Media SDK. Note user can't enable onevpl and libmfx together. oneVPL dispatcher source code: https://github.com/oneapi-src/oneVPL oneVPL GPU runtime for new Intel Gen platforms: https://github.com/oneapi-src/oneVPL-intel-gpu v5: - Rebased this patchset against the latest master - Do not define mfx related API in an export header [1] https://spec.oneapi.io/versions/latest/elements/oneVPL/source/index.html [2] https://github.com/Intel-Media-SDK/MediaSDK/#media-sdk-support-matrix [3] https://software.intel.com/content/www/us/en/develop/articles/upgrading-from-msdk-to-onevpl.html Haihao Xiang (10): configure: ensure --enable-libmfx uses libmfx 1.x configure: fix the check for MFX_CODEC_VP9 qsv: remove mfx/ prefix from mfx headers qsv: load user plugin for MFX_VERSION < 2.0 qsv: build audio related code when MFX_VERSION < 2.0 qsvenc: support multi-frame encode when MFX_VERSION < 2.0 qsvenc: support MFX_RATECONTROL_LA_EXT when MFX_VERSION < 2.0 qsv: support OPAQUE memory when MFX_VERSION < 2.0 qsv: use a new method to create mfx session when using oneVPL configure: add --enable-libvpl option configure| 28 ++- libavcodec/qsv.c | 220 -- libavcodec/qsv.h | 4 +- libavcodec/qsv_internal.h| 6 +- libavcodec/qsvdec.c | 21 +- libavcodec/qsvenc.c | 25 +- libavcodec/qsvenc.h | 9 +- libavcodec/qsvenc_h264.c | 3 +- libavcodec/qsvenc_hevc.c | 3 +- libavcodec/qsvenc_jpeg.c | 3 +- libavcodec/qsvenc_mpeg2.c| 3 +- libavcodec/qsvenc_vp9.c | 3 +- libavfilter/qsvvpp.c | 145 +++- libavfilter/qsvvpp.h | 12 +- libavfilter/vf_deinterlace_qsv.c | 73 +++--- libavfilter/vf_scale_qsv.c | 88 +++ libavutil/hwcontext_opencl.c | 2 +- libavutil/hwcontext_qsv.c| 383 ++- libavutil/hwcontext_qsv.h| 3 +- 19 files changed, 846 insertions(+), 188 deletions(-) -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v5 03/10] qsv: remove mfx/ prefix from mfx headers
The following Cflags has been added to libmfx.pc, so mfx/ prefix is no longer needed when including mfx headers in FFmpeg. Cflags: -I${includedir} -I${includedir}/mfx Some old versions of libmfx have the following Cflags in libmfx.pc Cflags: -I${includedir} We may add -I${includedir}/mfx to CFLAGS when running 'configure --enable-libmfx' for old versions of libmfx, if so, mfx headers without mfx/ prefix can be included too. If libmfx comes without pkg-config support, we may do a small change to the settings of the environment(e.g. set -I/opt/intel/mediasdk/include/mfx instead of -I/opt/intel/mediasdk/include to CFLAGS), then the build can find the mfx headers without mfx/ prefix After applying this change, we won't need to change #include for mfx headers when mfx headers are installed under a new directory. This is in preparation for oneVPL support (mfx headers in oneVPL are installed under vpl directory) --- configure| 13 + libavcodec/qsv.c | 8 libavcodec/qsv.h | 2 +- libavcodec/qsv_internal.h| 2 +- libavcodec/qsvdec.c | 2 +- libavcodec/qsvenc.c | 2 +- libavcodec/qsvenc.h | 2 +- libavcodec/qsvenc_h264.c | 2 +- libavcodec/qsvenc_hevc.c | 2 +- libavcodec/qsvenc_jpeg.c | 2 +- libavcodec/qsvenc_mpeg2.c| 2 +- libavcodec/qsvenc_vp9.c | 2 +- libavfilter/qsvvpp.h | 2 +- libavfilter/vf_deinterlace_qsv.c | 2 +- libavfilter/vf_scale_qsv.c | 2 +- libavutil/hwcontext_opencl.c | 2 +- libavutil/hwcontext_qsv.c| 2 +- libavutil/hwcontext_qsv.h| 2 +- 18 files changed, 29 insertions(+), 24 deletions(-) diff --git a/configure b/configure index b4a8c04a26..b7691d3218 100755 --- a/configure +++ b/configure @@ -6435,13 +6435,18 @@ enabled liblensfun&& require_pkg_config liblensfun lensfun lensfun.h lf_ # Media SDK or Intel Media Server Studio, these don't come with # pkg-config support. Instead, users should make sure that the build # can find the libraries and headers through other means. -enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit || - { require "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && + +enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfxvideo.h" MFXInit || +# Some old versions of libmfx have the following settings in libmfx.pc: +# includedir=/usr/include +# Cflags: -I${includedir} +# So add -I${includedir}/mfx to CFLAGS + { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit && add_cflags -I$($pkg_config --variable=includedir libmfx)/mfx; } || + { require "libmfx < 2.0" "mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && warn "build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,\n"\ "multi-frame encode, user plugins and LA_EXT rate control mode are enabled"; } - if enabled libmfx; then - check_cc MFX_CODEC_VP9 "mfx/mfxdefs.h mfx/mfxstructures.h" "MFX_CODEC_VP9" + check_cc MFX_CODEC_VP9 "mfxdefs.h mfxstructures.h" "MFX_CODEC_VP9" fi enabled libmodplug&& require_pkg_config libmodplug libmodplug libmodplug/modplug.h ModPlug_Load diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 9d08485c92..84f0401b0f 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include +#include +#include +#include #include #include @@ -39,7 +39,7 @@ #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) #if QSV_VERSION_ATLEAST(1, 12) -#include "mfx/mfxvp8.h" +#include "mfxvp8.h" #endif int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h index b77158ec26..04ae0d6f34 100644 --- a/libavcodec/qsv.h +++ b/libavcodec/qsv.h @@ -21,7 +21,7 @@ #ifndef AVCODEC_QSV_H #define AVCODEC_QSV_H -#include +#include #include "libavutil/buffer.h" diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 8090b748b3..24c3e9307e 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -39,7 +39,7 @@ #include "libavutil/hwcontext_vaapi.h" #endif -#include +#include #include "libavutil/frame.h" diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 8bce9f2cf0..1cadb846f5 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include "libavutil/common.h" #include "libavutil/fifo.h" diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 06f55604b5..7
[FFmpeg-devel] [PATCH v5 04/10] qsv: load user plugin for MFX_VERSION < 2.0
User plugin isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL Support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsv.c | 8 +++- libavcodec/qsv_internal.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 84f0401b0f..83056e5976 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -19,7 +19,6 @@ */ #include -#include #include #include @@ -37,11 +36,16 @@ #include "qsv_internal.h" #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) +#define QSV_HAVE_USER_PLUGIN!QSV_ONEVPL #if QSV_VERSION_ATLEAST(1, 12) #include "mfxvp8.h" #endif +#if QSV_HAVE_USER_PLUGIN +#include +#endif + int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) { switch (codec_id) { @@ -291,6 +295,7 @@ enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type) static int qsv_load_plugins(mfxSession session, const char *load_plugins, void *logctx) { +#if QSV_HAVE_USER_PLUGIN if (!load_plugins || !*load_plugins) return 0; @@ -334,6 +339,7 @@ load_plugin_fail: if (err < 0) return err; } +#endif return 0; diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 24c3e9307e..659417ded8 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -60,6 +60,8 @@ ((MFX_VERSION.Major > (MAJOR)) || \ (MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >= (MINOR))) +#define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0) + typedef struct QSVMid { AVBufferRef *hw_frames_ref; mfxHDLPair *handle_pair; -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v5 01/10] configure: ensure --enable-libmfx uses libmfx 1.x
Intel's oneVPL is a successor to MediaSDK, but removed some obsolete features of MediaSDK[1]. Some early versions of oneVPL still uses libmfx as library name[2], however some of obsolete features, including OPAQUE memory, multi-frame encode, user plugins and LA_EXT rate control mode etc, have been enabled in QSV, so user can not use --enable-libmfx to enable QSV if using an early version of oneVPL SDK. In order to make sure user builds FFmpeg against a right version of libmfx, this patch added a check for the version of libmfx and warning message about the used obsolete features. [1] https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html [2] https://github.com/oneapi-src/oneVPL --- configure | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 5e630e6e5d..960b030e24 100755 --- a/configure +++ b/configure @@ -6435,8 +6435,11 @@ enabled liblensfun&& require_pkg_config liblensfun lensfun lensfun.h lf_ # Media SDK or Intel Media Server Studio, these don't come with # pkg-config support. Instead, users should make sure that the build # can find the libraries and headers through other means. -enabled libmfx&& { check_pkg_config libmfx libmfx "mfx/mfxvideo.h" MFXInit || - { require libmfx "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } +enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit || + { require "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && + warn "build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,\n"\ +"multi-frame encode, user plugins and LA_EXT rate control mode are enabled"; } + if enabled libmfx; then check_cc MFX_CODEC_VP9 "mfx/mfxvp9.h mfx/mfxstructures.h" "MFX_CODEC_VP9" fi -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v5 05/10] qsv: build audio related code when MFX_VERSION < 2.0
Audio isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsv.c | 5 + libavfilter/qsvvpp.c | 6 ++ libavfilter/qsvvpp.h | 2 ++ 3 files changed, 13 insertions(+) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 83056e5976..e0a124a5cb 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -37,6 +37,7 @@ #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) #define QSV_HAVE_USER_PLUGIN!QSV_ONEVPL +#define QSV_HAVE_AUDIO !QSV_ONEVPL #if QSV_VERSION_ATLEAST(1, 12) #include "mfxvp8.h" @@ -137,8 +138,10 @@ static const struct { { MFX_ERR_INVALID_VIDEO_PARAM, AVERROR(EINVAL), "invalid video parameters" }, { MFX_ERR_UNDEFINED_BEHAVIOR, AVERROR_BUG, "undefined behavior" }, { MFX_ERR_DEVICE_FAILED,AVERROR(EIO),"device failed" }, +#if QSV_HAVE_AUDIO { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM, AVERROR(EINVAL), "incompatible audio parameters"}, { MFX_ERR_INVALID_AUDIO_PARAM, AVERROR(EINVAL), "invalid audio parameters" }, +#endif { MFX_WRN_IN_EXECUTION, 0, "operation in execution" }, { MFX_WRN_DEVICE_BUSY, 0, "device busy" }, @@ -148,7 +151,9 @@ static const struct { { MFX_WRN_VALUE_NOT_CHANGED,0, "value is saturated" }, { MFX_WRN_OUT_OF_RANGE, 0, "value out of range" }, { MFX_WRN_FILTER_SKIPPED, 0, "filter skipped" }, +#if QSV_HAVE_AUDIO { MFX_WRN_INCOMPATIBLE_AUDIO_PARAM, 0, "incompatible audio parameters"}, +#endif }; /** diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index d1218355c7..1113d27ba1 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -38,6 +38,8 @@ #define IS_SYSTEM_MEMORY(mode) (mode & MFX_MEMTYPE_SYSTEM_MEMORY) #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) +#define QSV_HAVE_AUDIO !QSV_ONEVPL + static const AVRational default_tb = { 1, 9 }; static const struct { @@ -95,8 +97,10 @@ static const struct { { MFX_ERR_INVALID_VIDEO_PARAM, AVERROR(EINVAL), "invalid video parameters" }, { MFX_ERR_UNDEFINED_BEHAVIOR, AVERROR_BUG, "undefined behavior" }, { MFX_ERR_DEVICE_FAILED,AVERROR(EIO),"device failed" }, +#if QSV_HAVE_AUDIO { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM, AVERROR(EINVAL), "incompatible audio parameters"}, { MFX_ERR_INVALID_AUDIO_PARAM, AVERROR(EINVAL), "invalid audio parameters" }, +#endif { MFX_WRN_IN_EXECUTION, 0, "operation in execution" }, { MFX_WRN_DEVICE_BUSY, 0, "device busy" }, @@ -106,7 +110,9 @@ static const struct { { MFX_WRN_VALUE_NOT_CHANGED,0, "value is saturated" }, { MFX_WRN_OUT_OF_RANGE, 0, "value out of range" }, { MFX_WRN_FILTER_SKIPPED, 0, "filter skipped" }, +#if QSV_HAVE_AUDIO { MFX_WRN_INCOMPATIBLE_AUDIO_PARAM, 0, "incompatible audio parameters"}, +#endif }; static int qsv_map_error(mfxStatus mfx_err, const char **desc) diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index 8c0cf3ed95..46e90c1d2c 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -40,6 +40,8 @@ ((MFX_VERSION.Major > (MAJOR)) || \ (MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >= (MINOR))) +#define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0) + typedef struct QSVFrame { AVFrame *frame; mfxFrameSurface1 surface; -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v5 08/10] qsv: support OPAQUE memory when MFX_VERSION < 2.0
OPAQUE memory isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsv.c | 4 ++ libavcodec/qsv.h | 2 + libavcodec/qsv_internal.h| 1 + libavcodec/qsvdec.c | 9 libavcodec/qsvenc.c | 21 + libavcodec/qsvenc.h | 2 + libavfilter/qsvvpp.c | 26 ++- libavfilter/qsvvpp.h | 3 ++ libavfilter/vf_deinterlace_qsv.c | 57 +--- libavfilter/vf_scale_qsv.c | 74 ++-- libavutil/hwcontext_qsv.c| 56 +--- 11 files changed, 181 insertions(+), 74 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index e0a124a5cb..d6f77908e4 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -89,10 +89,14 @@ static const struct { } qsv_iopatterns[] = { {MFX_IOPATTERN_IN_VIDEO_MEMORY, "input is video memory surface" }, {MFX_IOPATTERN_IN_SYSTEM_MEMORY,"input is system memory surface" }, +#if QSV_HAVE_OPAQUE {MFX_IOPATTERN_IN_OPAQUE_MEMORY,"input is opaque memory surface" }, +#endif {MFX_IOPATTERN_OUT_VIDEO_MEMORY,"output is video memory surface" }, {MFX_IOPATTERN_OUT_SYSTEM_MEMORY, "output is system memory surface" }, +#if QSV_HAVE_OPAQUE {MFX_IOPATTERN_OUT_OPAQUE_MEMORY, "output is opaque memory surface" }, +#endif }; int ff_qsv_print_iopattern(void *log_ctx, int mfx_iopattern, diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h index 04ae0d6f34..c156b08d07 100644 --- a/libavcodec/qsv.h +++ b/libavcodec/qsv.h @@ -61,6 +61,8 @@ typedef struct AVQSVContext { * required by the encoder and the user-provided value nb_opaque_surfaces. * The array of the opaque surfaces will be exported to the caller through * the opaque_surfaces field. + * + * The caller must set this field to zero for oneVPL (MFX_VERSION >= 2.0) */ int opaque_alloc; diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 659417ded8..ff50b41de8 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -61,6 +61,7 @@ (MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >= (MINOR))) #define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0) +#define QSV_HAVE_OPAQUE !QSV_ONEVPL typedef struct QSVMid { AVBufferRef *hw_frames_ref; diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 1cadb846f5..9395a1fd9a 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -171,7 +171,11 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses ret = ff_qsv_init_session_frames(avctx, &q->internal_qs.session, &q->frames_ctx, q->load_plugins, +#if QSV_HAVE_OPAQUE q->iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY, +#else + 0, +#endif q->gpu_copy); if (ret < 0) { av_buffer_unref(&q->frames_ctx.hw_frames_ctx); @@ -282,10 +286,15 @@ static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixel AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; if (!iopattern) { +#if QSV_HAVE_OPAQUE if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME) iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY; else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY; +#else +if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) +iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY; +#endif } } diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 6c6494745f..546efd9668 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1029,6 +1029,7 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q) return 0; } +#if QSV_HAVE_OPAQUE static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q) { AVQSVContext *qsv = avctx->hwaccel_context; @@ -1065,6 +1066,7 @@ static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q) return 0; } +#endif static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q) { @@ -1080,7 +1082,11 @@ static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q) ret = ff_qsv_init_session_frames(avctx, &q->internal_qs.session, &q->frames_ctx, q->load_plugins, +#if QSV_HAVE_OPAQUE q->param.IOPattern == MFX_IOPATTERN_IN_OPAQUE_MEMORY, +#els
[FFmpeg-devel] [PATCH v5 02/10] configure: fix the check for MFX_CODEC_VP9
The data structures for VP9 in mfxvp9.h is wrapped by MFX_VERSION_NEXT, which means those data structures have never been used in a public release. Actually MFX_CODEC_VP9 and other VP9 stuffs is added in mfxstructures.h. In addition, mfxdefs.h is included in mfxvp9.h, so we may use the check in this patch for MFX_CODEC_VP9 This is in preparation for oneVPL support because mfxvp9.h is removed from oneVPL [1] [1]: https://github.com/oneapi-src/oneVPL --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 960b030e24..b4a8c04a26 100755 --- a/configure +++ b/configure @@ -6441,7 +6441,7 @@ enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfx "multi-frame encode, user plugins and LA_EXT rate control mode are enabled"; } if enabled libmfx; then - check_cc MFX_CODEC_VP9 "mfx/mfxvp9.h mfx/mfxstructures.h" "MFX_CODEC_VP9" + check_cc MFX_CODEC_VP9 "mfx/mfxdefs.h mfx/mfxstructures.h" "MFX_CODEC_VP9" fi enabled libmodplug&& require_pkg_config libmodplug libmodplug libmodplug/modplug.h ModPlug_Load -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v5 06/10] qsvenc: support multi-frame encode when MFX_VERSION < 2.0
Multi-frame encode isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsvenc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index 7a71ffe98f..93af4d1198 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -64,7 +64,7 @@ #define QSV_HAVE_ICQQSV_VERSION_ATLEAST(1, 28) #define QSV_HAVE_VCM0 #define QSV_HAVE_QVBR QSV_VERSION_ATLEAST(1, 28) -#define QSV_HAVE_MF QSV_VERSION_ATLEAST(1, 25) +#define QSV_HAVE_MF QSV_VERSION_ATLEAST(1, 25) && !QSV_ONEVPL #endif #if !QSV_HAVE_LA_DS -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v5 09/10] qsv: use a new method to create mfx session when using oneVPL
In oneVPL, MFXLoad() and MFXCreateSession() are required to create a workable mfx session[1] Add AccelerationMode config filter for D3D9/D3D11 session (galinart) The default device is changed to d3d11va for oneVPL when both d3d11va and dxva2 are enabled on Microsoft Windows This is in preparation for oneVPL support [1] https://spec.oneapi.io/versions/latest/elements/oneVPL/source/programming_guide/VPL_prg_session.html#onevpl-dispatcher Signed-off-by: galinart --- libavcodec/qsv.c | 197 +-- libavcodec/qsv_internal.h| 1 + libavcodec/qsvdec.c | 10 + libavcodec/qsvenc.h | 3 + libavcodec/qsvenc_h264.c | 1 - libavcodec/qsvenc_hevc.c | 1 - libavcodec/qsvenc_jpeg.c | 1 - libavcodec/qsvenc_mpeg2.c| 1 - libavcodec/qsvenc_vp9.c | 1 - libavfilter/qsvvpp.c | 113 ++- libavfilter/qsvvpp.h | 5 + libavfilter/vf_deinterlace_qsv.c | 14 +- libavfilter/vf_scale_qsv.c | 12 +- libavutil/hwcontext_qsv.c| 325 +++ libavutil/hwcontext_qsv.h| 1 + 15 files changed, 597 insertions(+), 89 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index d6f77908e4..46d3ac95eb 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -47,6 +47,12 @@ #include #endif +#if QSV_ONEVPL +#include +#else +#define MFXUnload(a) do { } while(0) +#endif + int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) { switch (codec_id) { @@ -387,6 +393,164 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) } #endif //AVCODEC_QSV_LINUX_SESSION_HANDLE +#if QSV_ONEVPL + +static int qsv_create_mfx_session(AVCodecContext *avctx, + mfxIMPL implementation, + mfxVersion *pver, + int gpu_copy, + mfxSession *psession, + void **ploader) +{ +mfxStatus sts; +mfxLoader loader = NULL; +mfxSession session = NULL; +mfxConfig cfg; +mfxVariant impl_value; +uint32_t impl_idx = 0; + +*psession = NULL; + +/* Don't create a new MFX loader if the input loader is valid */ +if (*ploader == NULL) { +av_log(avctx, AV_LOG_VERBOSE, + "Use Intel(R) oneVPL to create MFX session, the required " + "implementation version is %d.%d\n", + pver->Major, pver->Minor); + +loader = MFXLoad(); + +if (!loader) { +av_log(avctx, AV_LOG_ERROR, "Error creating a MFX loader\n"); +goto fail; +} + +/* Create configurations for implementation */ +cfg = MFXCreateConfig(loader); + +if (!cfg) { +av_log(avctx, AV_LOG_ERROR, "Error creating a MFX configurations\n"); +goto fail; +} + +impl_value.Type = MFX_VARIANT_TYPE_U32; +impl_value.Data.U32 = (implementation == MFX_IMPL_SOFTWARE) ? +MFX_IMPL_TYPE_SOFTWARE : MFX_IMPL_TYPE_HARDWARE; +sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.Impl", impl_value); + +if (sts != MFX_ERR_NONE) { +av_log(avctx, AV_LOG_ERROR, "Error adding a MFX configuration " + "property: %d\n", sts); +goto fail; +} + +impl_value.Type = MFX_VARIANT_TYPE_U32; +impl_value.Data.U32 = pver->Version; +sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.ApiVersion.Version", + impl_value); + +if (sts != MFX_ERR_NONE) { +av_log(avctx, AV_LOG_ERROR, "Error adding a MFX configuration " + "property: %d\n", sts); +goto fail; +} +} else { +av_log(avctx, AV_LOG_VERBOSE, + "Use Intel(R) oneVPL to create MFX session with the specified MFX loader\n"); + +loader = *ploader; +} + +while (1) { +/* Enumerate all implementations */ +mfxImplDescription *impl_desc; + +sts = MFXEnumImplementations(loader, impl_idx, + MFX_IMPLCAPS_IMPLDESCSTRUCTURE, + (mfxHDL *)&impl_desc); + +/* Failed to find an available implementation */ +if (sts == MFX_ERR_NOT_FOUND) +break; +else if (sts != MFX_ERR_NONE) { +impl_idx++; +continue; +} + +sts = MFXCreateSession(loader, impl_idx, &session); +MFXDispReleaseImplDescription(loader, impl_desc); + +if (sts == MFX_ERR_NONE) +break; + +impl_idx++; +} + +if (sts != MFX_ERR_NONE) { +av_log(avctx, AV_LOG_ERROR, "Error creating a MFX session: %d.\n", sts); +got
[FFmpeg-devel] [PATCH v5 10/10] configure: add --enable-libvpl option
This allows user to build FFmpeg against Intel oneVPL. oneVPL 2.2 is the required minimum version when building Intel oneVPL code. It will fail to run configure script if both libmfx and libvpl are enabled. It is recommended to use oneVPL for new work, even for currently available hardwares [1] [1] https://software.intel.com/content/www/us/en/develop/articles/upgrading-from-msdk-to-onevpl.html --- configure | 26 -- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/configure b/configure index b7691d3218..5ccb2592a6 100755 --- a/configure +++ b/configure @@ -337,6 +337,7 @@ External library support: --disable-ffnvcodec disable dynamically linked Nvidia code [autodetect] --enable-libdrm enable DRM code (Linux) [no] --enable-libmfx enable Intel MediaSDK (AKA Quick Sync Video) code via libmfx [no] + --enable-libvpl enable Intel oneVPL code via libvpl if libmfx is not used [no] --enable-libnpp enable Nvidia Performance Primitives-based code [no] --enable-mmalenable Broadcom Multi-Media Abstraction Layer (Raspberry Pi) via MMAL [no] --disable-nvdec disable Nvidia video decoding acceleration (via hwaccel) [autodetect] @@ -1895,6 +1896,7 @@ HWACCEL_LIBRARY_NONFREE_LIST=" HWACCEL_LIBRARY_LIST=" $HWACCEL_LIBRARY_NONFREE_LIST libmfx +libvpl mmal omx opencl @@ -6429,22 +6431,34 @@ enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -li enabled libklvanc && require libklvanc libklvanc/vanc.h klvanc_context_create -lklvanc enabled libkvazaar&& require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get enabled liblensfun&& require_pkg_config liblensfun lensfun lensfun.h lf_db_new + +if enabled libmfx && enabled libvpl; then + die "ERROR: can not use libmfx and libvpl together" # While it may appear that require is being used as a pkg-config # fallback for libmfx, it is actually being used to detect a different # installation route altogether. If libmfx is installed via the Intel # Media SDK or Intel Media Server Studio, these don't come with # pkg-config support. Instead, users should make sure that the build # can find the libraries and headers through other means. - -enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfxvideo.h" MFXInit || +elif enabled libmfx; then +{ check_pkg_config libmfx "libmfx < 2.0" "mfxvideo.h" MFXInit || \ # Some old versions of libmfx have the following settings in libmfx.pc: # includedir=/usr/include # Cflags: -I${includedir} # So add -I${includedir}/mfx to CFLAGS - { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit && add_cflags -I$($pkg_config --variable=includedir libmfx)/mfx; } || - { require "libmfx < 2.0" "mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && - warn "build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,\n"\ -"multi-frame encode, user plugins and LA_EXT rate control mode are enabled"; } + { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit && add_cflags -I$($pkg_config --variable=includedir libmfx)/mfx; } || + { require "libmfx < 2.0" "mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && +warn "build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,\n"\ + "multi-frame encode, user plugins and LA_EXT rate control mode are enabled" +elif enabled libvpl; then +# Consider pkg-config only. The name of libmfx is still used in the following check for --enable-libvpl option +# because QSV has dependency on libmfx, we can use the same dependency if using libmfx in this check. +check_pkg_config libmfx "vpl >= 2.2" "mfxvideo.h mfxdispatcher.h" MFXLoad && \ +warn "build FFmpeg against oneVPL 2.2+, OPAQUE memory, multi-frame encode, user plugins\n"\ + "and LA_EXT rate control mode in FFmpeg QSV won't be supported." || +die "ERROR: libvpl >= 2.2 not found" +fi + if enabled libmfx; then check_cc MFX_CODEC_VP9 "mfxdefs.h mfxstructures.h" "MFX_CODEC_VP9" fi -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v5 07/10] qsvenc: support MFX_RATECONTROL_LA_EXT when MFX_VERSION < 2.0
MFX_RATECONTROL_LA_EXT isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 7eaa680ae4..6c6494745f 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -100,7 +100,7 @@ static const struct { #if QSV_HAVE_VCM { MFX_RATECONTROL_VCM, "VCM" }, #endif -#if QSV_VERSION_ATLEAST(1, 10) +#if QSV_VERSION_ATLEAST(1, 10) && !QSV_ONEVPL { MFX_RATECONTROL_LA_EXT, "LA_EXT" }, #endif #if QSV_HAVE_LA_HRD -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] qsvenc_hevc: Enable look ahead with ExtBRC
From: Daniel Socek Signed-off-by: Daniel Socek Signed-off-by: Haihao Xiang --- libavcodec/qsvenc.c | 3 +++ libavcodec/qsvenc_hevc.c | 1 + 2 files changed, 4 insertions(+) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 06f55604b5..e21a9b1207 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -610,6 +610,9 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) switch (q->param.mfx.RateControlMethod) { case MFX_RATECONTROL_CBR: case MFX_RATECONTROL_VBR: +if (q->extbrc) { +q->extco2.LookAheadDepth = q->look_ahead_depth; +} #if QSV_HAVE_VCM case MFX_RATECONTROL_VCM: #endif diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index b7b2f5633e..8af2aa0c07 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -248,6 +248,7 @@ static const AVOption options[] = { { "tile_rows", "Number of rows for tiled encoding", OFFSET(qsv.tile_rows),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE }, { "recovery_point_sei", "Insert recovery point SEI messages", OFFSET(qsv.recovery_point_sei), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, { "aud", "Insert the Access Unit Delimiter NAL", OFFSET(qsv.aud), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE}, +{ "look_ahead_depth", "Depth of look ahead in number frames", OFFSET(qsv.look_ahead_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, VE }, { NULL }, }; -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 00/10] make QSV works with the Intel's oneVPL
The oneAPI Video Processing Library (oneVPL) is a single interface for encode, decode and video processing[1]. oneVPL is a successor to Intel(R) Media SDK, but removed obsolete features. Intel(R) Media SDK lifetime comes to an end now, new features for new Intel Gen platforms will be supported in oneVPL only[2]. It is recommended to use oneVPL for new work, even for currently available hardwares[3]. Hence, this patchset added a new option --enable-onevpl to bring the support for oneVPL in QSV. New features for oneVPL will be implemented in other patchset. --enble-libmfx option still works with Intel(R) Media SDK. Note user can't enable onevpl and libmfx together. oneVPL dispatcher source code: https://github.com/oneapi-src/oneVPL oneVPL GPU runtime for new Intel Gen platforms: https://github.com/oneapi-src/oneVPL-intel-gpu v6: - Use ${libmfx_incdir} in configure - Don't define mfx related function in an exported header - Rebased this patchset against the latest master and fixed bugs [1] https://spec.oneapi.io/versions/latest/elements/oneVPL/source/index.html [2] https://github.com/Intel-Media-SDK/MediaSDK/#media-sdk-support-matrix [3] https://software.intel.com/content/www/us/en/develop/articles/upgrading-from-msdk-to-onevpl.html Haihao Xiang (10): configure: ensure --enable-libmfx uses libmfx 1.x configure: fix the check for MFX_CODEC_VP9 qsv: remove mfx/ prefix from mfx headers qsv: load user plugin for MFX_VERSION < 2.0 qsv: build audio related code when MFX_VERSION < 2.0 qsvenc: support multi-frame encode when MFX_VERSION < 2.0 qsvenc: support MFX_RATECONTROL_LA_EXT when MFX_VERSION < 2.0 qsv: support OPAQUE memory when MFX_VERSION < 2.0 qsv: use a new method to create mfx session when using oneVPL configure: add --enable-libvpl option configure| 29 ++- libavcodec/qsv.c | 220 ++-- libavcodec/qsv.h | 4 +- libavcodec/qsv_internal.h| 6 +- libavcodec/qsvdec.c | 21 +- libavcodec/qsvenc.c | 25 +- libavcodec/qsvenc.h | 9 +- libavcodec/qsvenc_h264.c | 3 +- libavcodec/qsvenc_hevc.c | 3 +- libavcodec/qsvenc_jpeg.c | 3 +- libavcodec/qsvenc_mpeg2.c| 3 +- libavcodec/qsvenc_vp9.c | 3 +- libavfilter/qsvvpp.c | 145 ++- libavfilter/qsvvpp.h | 12 +- libavfilter/vf_deinterlace_qsv.c | 73 +++--- libavfilter/vf_scale_qsv.c | 88 --- libavutil/hwcontext_d3d11va.c| 13 + libavutil/hwcontext_d3d11va.h| 5 + libavutil/hwcontext_dxva2.c | 8 + libavutil/hwcontext_dxva2.h | 4 + libavutil/hwcontext_opencl.c | 2 +- libavutil/hwcontext_qsv.c| 423 +++ libavutil/hwcontext_qsv.h| 3 +- libavutil/hwcontext_vaapi.c | 13 + libavutil/hwcontext_vaapi.h | 4 + 25 files changed, 934 insertions(+), 188 deletions(-) -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 01/10] configure: ensure --enable-libmfx uses libmfx 1.x
Intel's oneVPL is a successor to MediaSDK, but removed some obsolete features of MediaSDK[1]. Some early versions of oneVPL still uses libmfx as library name[2], however some of obsolete features, including OPAQUE memory, multi-frame encode, user plugins and LA_EXT rate control mode etc, have been enabled in QSV, so user can not use --enable-libmfx to enable QSV if using an early version of oneVPL SDK. In order to make sure user builds FFmpeg against a right version of libmfx, this patch added a check for the version of libmfx and warning message about the used obsolete features. [1] https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html [2] https://github.com/oneapi-src/oneVPL --- configure | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 92610c7edc..f89e769684 100755 --- a/configure +++ b/configure @@ -6438,8 +6438,11 @@ enabled liblensfun&& require_pkg_config liblensfun lensfun lensfun.h lf_ # Media SDK or Intel Media Server Studio, these don't come with # pkg-config support. Instead, users should make sure that the build # can find the libraries and headers through other means. -enabled libmfx&& { check_pkg_config libmfx libmfx "mfx/mfxvideo.h" MFXInit || - { require libmfx "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } +enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit || + { require "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && + warn "build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,\n"\ +"multi-frame encode, user plugins and LA_EXT rate control mode are enabled"; } + if enabled libmfx; then check_cc MFX_CODEC_VP9 "mfx/mfxvp9.h mfx/mfxstructures.h" "MFX_CODEC_VP9" fi -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 02/10] configure: fix the check for MFX_CODEC_VP9
The data structures for VP9 in mfxvp9.h is wrapped by MFX_VERSION_NEXT, which means those data structures have never been used in a public release. Actually MFX_CODEC_VP9 and other VP9 stuffs is added in mfxstructures.h. In addition, mfxdefs.h is included in mfxvp9.h, so we may use the check in this patch for MFX_CODEC_VP9 This is in preparation for oneVPL support because mfxvp9.h is removed from oneVPL [1] [1]: https://github.com/oneapi-src/oneVPL --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index f89e769684..0204d230c7 100755 --- a/configure +++ b/configure @@ -6444,7 +6444,7 @@ enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfx "multi-frame encode, user plugins and LA_EXT rate control mode are enabled"; } if enabled libmfx; then - check_cc MFX_CODEC_VP9 "mfx/mfxvp9.h mfx/mfxstructures.h" "MFX_CODEC_VP9" + check_cc MFX_CODEC_VP9 "mfx/mfxdefs.h mfx/mfxstructures.h" "MFX_CODEC_VP9" fi enabled libmodplug&& require_pkg_config libmodplug libmodplug libmodplug/modplug.h ModPlug_Load -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 03/10] qsv: remove mfx/ prefix from mfx headers
The following Cflags has been added to libmfx.pc, so mfx/ prefix is no longer needed when including mfx headers in FFmpeg. Cflags: -I${includedir} -I${includedir}/mfx Some old versions of libmfx have the following Cflags in libmfx.pc Cflags: -I${includedir} We may add -I${includedir}/mfx to CFLAGS when running 'configure --enable-libmfx' for old versions of libmfx, if so, mfx headers without mfx/ prefix can be included too. If libmfx comes without pkg-config support, we may do a small change to the settings of the environment(e.g. set -I/opt/intel/mediasdk/include/mfx instead of -I/opt/intel/mediasdk/include to CFLAGS), then the build can find the mfx headers without mfx/ prefix After applying this change, we won't need to change #include for mfx headers when mfx headers are installed under a new directory. This is in preparation for oneVPL support (mfx headers in oneVPL are installed under vpl directory) --- configure| 13 + libavcodec/qsv.c | 8 libavcodec/qsv.h | 2 +- libavcodec/qsv_internal.h| 2 +- libavcodec/qsvdec.c | 2 +- libavcodec/qsvenc.c | 2 +- libavcodec/qsvenc.h | 2 +- libavcodec/qsvenc_h264.c | 2 +- libavcodec/qsvenc_hevc.c | 2 +- libavcodec/qsvenc_jpeg.c | 2 +- libavcodec/qsvenc_mpeg2.c| 2 +- libavcodec/qsvenc_vp9.c | 2 +- libavfilter/qsvvpp.h | 2 +- libavfilter/vf_deinterlace_qsv.c | 2 +- libavfilter/vf_scale_qsv.c | 2 +- libavutil/hwcontext_opencl.c | 2 +- libavutil/hwcontext_qsv.c| 2 +- libavutil/hwcontext_qsv.h| 2 +- 18 files changed, 29 insertions(+), 24 deletions(-) diff --git a/configure b/configure index 0204d230c7..cc5894dcac 100755 --- a/configure +++ b/configure @@ -6438,13 +6438,18 @@ enabled liblensfun&& require_pkg_config liblensfun lensfun lensfun.h lf_ # Media SDK or Intel Media Server Studio, these don't come with # pkg-config support. Instead, users should make sure that the build # can find the libraries and headers through other means. -enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit || - { require "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && + +enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfxvideo.h" MFXInit || +# Some old versions of libmfx have the following settings in libmfx.pc: +# includedir=/usr/include +# Cflags: -I${includedir} +# So add -I${includedir}/mfx to CFLAGS + { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit && add_cflags -I${libmfx_incdir}/mfx; } || + { require "libmfx < 2.0" "mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && warn "build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,\n"\ "multi-frame encode, user plugins and LA_EXT rate control mode are enabled"; } - if enabled libmfx; then - check_cc MFX_CODEC_VP9 "mfx/mfxdefs.h mfx/mfxstructures.h" "MFX_CODEC_VP9" + check_cc MFX_CODEC_VP9 "mfxdefs.h mfxstructures.h" "MFX_CODEC_VP9" fi enabled libmodplug&& require_pkg_config libmodplug libmodplug libmodplug/modplug.h ModPlug_Load diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 9d08485c92..84f0401b0f 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include +#include +#include +#include #include #include @@ -39,7 +39,7 @@ #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) #if QSV_VERSION_ATLEAST(1, 12) -#include "mfx/mfxvp8.h" +#include "mfxvp8.h" #endif int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h index b77158ec26..04ae0d6f34 100644 --- a/libavcodec/qsv.h +++ b/libavcodec/qsv.h @@ -21,7 +21,7 @@ #ifndef AVCODEC_QSV_H #define AVCODEC_QSV_H -#include +#include #include "libavutil/buffer.h" diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 8090b748b3..24c3e9307e 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -39,7 +39,7 @@ #include "libavutil/hwcontext_vaapi.h" #endif -#include +#include #include "libavutil/frame.h" diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 8bce9f2cf0..1cadb846f5 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include "libavutil/common.h" #include "libavutil/fifo.h" diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 06f55604b5..7eaa680ae4 100644 --- a/libav
[FFmpeg-devel] [PATCH v6 04/10] qsv: load user plugin for MFX_VERSION < 2.0
User plugin isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL Support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsv.c | 8 +++- libavcodec/qsv_internal.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 84f0401b0f..83056e5976 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -19,7 +19,6 @@ */ #include -#include #include #include @@ -37,11 +36,16 @@ #include "qsv_internal.h" #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) +#define QSV_HAVE_USER_PLUGIN!QSV_ONEVPL #if QSV_VERSION_ATLEAST(1, 12) #include "mfxvp8.h" #endif +#if QSV_HAVE_USER_PLUGIN +#include +#endif + int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) { switch (codec_id) { @@ -291,6 +295,7 @@ enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type) static int qsv_load_plugins(mfxSession session, const char *load_plugins, void *logctx) { +#if QSV_HAVE_USER_PLUGIN if (!load_plugins || !*load_plugins) return 0; @@ -334,6 +339,7 @@ load_plugin_fail: if (err < 0) return err; } +#endif return 0; diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 24c3e9307e..659417ded8 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -60,6 +60,8 @@ ((MFX_VERSION.Major > (MAJOR)) || \ (MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >= (MINOR))) +#define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0) + typedef struct QSVMid { AVBufferRef *hw_frames_ref; mfxHDLPair *handle_pair; -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 05/10] qsv: build audio related code when MFX_VERSION < 2.0
Audio isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsv.c | 5 + libavfilter/qsvvpp.c | 6 ++ libavfilter/qsvvpp.h | 2 ++ 3 files changed, 13 insertions(+) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 83056e5976..e0a124a5cb 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -37,6 +37,7 @@ #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) #define QSV_HAVE_USER_PLUGIN!QSV_ONEVPL +#define QSV_HAVE_AUDIO !QSV_ONEVPL #if QSV_VERSION_ATLEAST(1, 12) #include "mfxvp8.h" @@ -137,8 +138,10 @@ static const struct { { MFX_ERR_INVALID_VIDEO_PARAM, AVERROR(EINVAL), "invalid video parameters" }, { MFX_ERR_UNDEFINED_BEHAVIOR, AVERROR_BUG, "undefined behavior" }, { MFX_ERR_DEVICE_FAILED,AVERROR(EIO),"device failed" }, +#if QSV_HAVE_AUDIO { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM, AVERROR(EINVAL), "incompatible audio parameters"}, { MFX_ERR_INVALID_AUDIO_PARAM, AVERROR(EINVAL), "invalid audio parameters" }, +#endif { MFX_WRN_IN_EXECUTION, 0, "operation in execution" }, { MFX_WRN_DEVICE_BUSY, 0, "device busy" }, @@ -148,7 +151,9 @@ static const struct { { MFX_WRN_VALUE_NOT_CHANGED,0, "value is saturated" }, { MFX_WRN_OUT_OF_RANGE, 0, "value out of range" }, { MFX_WRN_FILTER_SKIPPED, 0, "filter skipped" }, +#if QSV_HAVE_AUDIO { MFX_WRN_INCOMPATIBLE_AUDIO_PARAM, 0, "incompatible audio parameters"}, +#endif }; /** diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index d1218355c7..1113d27ba1 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -38,6 +38,8 @@ #define IS_SYSTEM_MEMORY(mode) (mode & MFX_MEMTYPE_SYSTEM_MEMORY) #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) +#define QSV_HAVE_AUDIO !QSV_ONEVPL + static const AVRational default_tb = { 1, 9 }; static const struct { @@ -95,8 +97,10 @@ static const struct { { MFX_ERR_INVALID_VIDEO_PARAM, AVERROR(EINVAL), "invalid video parameters" }, { MFX_ERR_UNDEFINED_BEHAVIOR, AVERROR_BUG, "undefined behavior" }, { MFX_ERR_DEVICE_FAILED,AVERROR(EIO),"device failed" }, +#if QSV_HAVE_AUDIO { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM, AVERROR(EINVAL), "incompatible audio parameters"}, { MFX_ERR_INVALID_AUDIO_PARAM, AVERROR(EINVAL), "invalid audio parameters" }, +#endif { MFX_WRN_IN_EXECUTION, 0, "operation in execution" }, { MFX_WRN_DEVICE_BUSY, 0, "device busy" }, @@ -106,7 +110,9 @@ static const struct { { MFX_WRN_VALUE_NOT_CHANGED,0, "value is saturated" }, { MFX_WRN_OUT_OF_RANGE, 0, "value out of range" }, { MFX_WRN_FILTER_SKIPPED, 0, "filter skipped" }, +#if QSV_HAVE_AUDIO { MFX_WRN_INCOMPATIBLE_AUDIO_PARAM, 0, "incompatible audio parameters"}, +#endif }; static int qsv_map_error(mfxStatus mfx_err, const char **desc) diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index 8c0cf3ed95..46e90c1d2c 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -40,6 +40,8 @@ ((MFX_VERSION.Major > (MAJOR)) || \ (MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >= (MINOR))) +#define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0) + typedef struct QSVFrame { AVFrame *frame; mfxFrameSurface1 surface; -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 08/10] qsv: support OPAQUE memory when MFX_VERSION < 2.0
OPAQUE memory isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsv.c | 4 ++ libavcodec/qsv.h | 2 + libavcodec/qsv_internal.h| 1 + libavcodec/qsvdec.c | 9 libavcodec/qsvenc.c | 21 + libavcodec/qsvenc.h | 2 + libavfilter/qsvvpp.c | 26 ++- libavfilter/qsvvpp.h | 3 ++ libavfilter/vf_deinterlace_qsv.c | 57 +--- libavfilter/vf_scale_qsv.c | 74 ++-- libavutil/hwcontext_qsv.c| 56 +--- 11 files changed, 181 insertions(+), 74 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index e0a124a5cb..d6f77908e4 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -89,10 +89,14 @@ static const struct { } qsv_iopatterns[] = { {MFX_IOPATTERN_IN_VIDEO_MEMORY, "input is video memory surface" }, {MFX_IOPATTERN_IN_SYSTEM_MEMORY,"input is system memory surface" }, +#if QSV_HAVE_OPAQUE {MFX_IOPATTERN_IN_OPAQUE_MEMORY,"input is opaque memory surface" }, +#endif {MFX_IOPATTERN_OUT_VIDEO_MEMORY,"output is video memory surface" }, {MFX_IOPATTERN_OUT_SYSTEM_MEMORY, "output is system memory surface" }, +#if QSV_HAVE_OPAQUE {MFX_IOPATTERN_OUT_OPAQUE_MEMORY, "output is opaque memory surface" }, +#endif }; int ff_qsv_print_iopattern(void *log_ctx, int mfx_iopattern, diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h index 04ae0d6f34..c156b08d07 100644 --- a/libavcodec/qsv.h +++ b/libavcodec/qsv.h @@ -61,6 +61,8 @@ typedef struct AVQSVContext { * required by the encoder and the user-provided value nb_opaque_surfaces. * The array of the opaque surfaces will be exported to the caller through * the opaque_surfaces field. + * + * The caller must set this field to zero for oneVPL (MFX_VERSION >= 2.0) */ int opaque_alloc; diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 659417ded8..ff50b41de8 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -61,6 +61,7 @@ (MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >= (MINOR))) #define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0) +#define QSV_HAVE_OPAQUE !QSV_ONEVPL typedef struct QSVMid { AVBufferRef *hw_frames_ref; diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 1cadb846f5..9395a1fd9a 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -171,7 +171,11 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses ret = ff_qsv_init_session_frames(avctx, &q->internal_qs.session, &q->frames_ctx, q->load_plugins, +#if QSV_HAVE_OPAQUE q->iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY, +#else + 0, +#endif q->gpu_copy); if (ret < 0) { av_buffer_unref(&q->frames_ctx.hw_frames_ctx); @@ -282,10 +286,15 @@ static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixel AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; if (!iopattern) { +#if QSV_HAVE_OPAQUE if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME) iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY; else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY; +#else +if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) +iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY; +#endif } } diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 6c6494745f..546efd9668 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1029,6 +1029,7 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q) return 0; } +#if QSV_HAVE_OPAQUE static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q) { AVQSVContext *qsv = avctx->hwaccel_context; @@ -1065,6 +1066,7 @@ static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q) return 0; } +#endif static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q) { @@ -1080,7 +1082,11 @@ static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q) ret = ff_qsv_init_session_frames(avctx, &q->internal_qs.session, &q->frames_ctx, q->load_plugins, +#if QSV_HAVE_OPAQUE q->param.IOPattern == MFX_IOPATTERN_IN_OPAQUE_MEMORY, +#els
[FFmpeg-devel] [PATCH v6 09/10] qsv: use a new method to create mfx session when using oneVPL
In oneVPL, MFXLoad() and MFXCreateSession() are required to create a workable mfx session[1] Add AccelerationMode config filter for D3D9/D3D11 session (galinart) The default device is changed to d3d11va for oneVPL when both d3d11va and dxva2 are enabled on Microsoft Windows This is in preparation for oneVPL support [1] https://spec.oneapi.io/versions/latest/elements/oneVPL/source/programming_guide/VPL_prg_session.html#onevpl-dispatcher Signed-off-by: galinart --- libavcodec/qsv.c | 197 +++-- libavcodec/qsv_internal.h| 1 + libavcodec/qsvdec.c | 10 + libavcodec/qsvenc.h | 3 + libavcodec/qsvenc_h264.c | 1 - libavcodec/qsvenc_hevc.c | 1 - libavcodec/qsvenc_jpeg.c | 1 - libavcodec/qsvenc_mpeg2.c| 1 - libavcodec/qsvenc_vp9.c | 1 - libavfilter/qsvvpp.c | 113 +- libavfilter/qsvvpp.h | 5 + libavfilter/vf_deinterlace_qsv.c | 14 +- libavfilter/vf_scale_qsv.c | 12 +- libavutil/hwcontext_d3d11va.c| 13 ++ libavutil/hwcontext_d3d11va.h| 5 + libavutil/hwcontext_dxva2.c | 8 + libavutil/hwcontext_dxva2.h | 4 + libavutil/hwcontext_qsv.c| 365 +++ libavutil/hwcontext_qsv.h| 1 + libavutil/hwcontext_vaapi.c | 13 ++ libavutil/hwcontext_vaapi.h | 4 + 21 files changed, 684 insertions(+), 89 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index d6f77908e4..46d3ac95eb 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -47,6 +47,12 @@ #include #endif +#if QSV_ONEVPL +#include +#else +#define MFXUnload(a) do { } while(0) +#endif + int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) { switch (codec_id) { @@ -387,6 +393,164 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) } #endif //AVCODEC_QSV_LINUX_SESSION_HANDLE +#if QSV_ONEVPL + +static int qsv_create_mfx_session(AVCodecContext *avctx, + mfxIMPL implementation, + mfxVersion *pver, + int gpu_copy, + mfxSession *psession, + void **ploader) +{ +mfxStatus sts; +mfxLoader loader = NULL; +mfxSession session = NULL; +mfxConfig cfg; +mfxVariant impl_value; +uint32_t impl_idx = 0; + +*psession = NULL; + +/* Don't create a new MFX loader if the input loader is valid */ +if (*ploader == NULL) { +av_log(avctx, AV_LOG_VERBOSE, + "Use Intel(R) oneVPL to create MFX session, the required " + "implementation version is %d.%d\n", + pver->Major, pver->Minor); + +loader = MFXLoad(); + +if (!loader) { +av_log(avctx, AV_LOG_ERROR, "Error creating a MFX loader\n"); +goto fail; +} + +/* Create configurations for implementation */ +cfg = MFXCreateConfig(loader); + +if (!cfg) { +av_log(avctx, AV_LOG_ERROR, "Error creating a MFX configurations\n"); +goto fail; +} + +impl_value.Type = MFX_VARIANT_TYPE_U32; +impl_value.Data.U32 = (implementation == MFX_IMPL_SOFTWARE) ? +MFX_IMPL_TYPE_SOFTWARE : MFX_IMPL_TYPE_HARDWARE; +sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.Impl", impl_value); + +if (sts != MFX_ERR_NONE) { +av_log(avctx, AV_LOG_ERROR, "Error adding a MFX configuration " + "property: %d\n", sts); +goto fail; +} + +impl_value.Type = MFX_VARIANT_TYPE_U32; +impl_value.Data.U32 = pver->Version; +sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.ApiVersion.Version", + impl_value); + +if (sts != MFX_ERR_NONE) { +av_log(avctx, AV_LOG_ERROR, "Error adding a MFX configuration " + "property: %d\n", sts); +goto fail; +} +} else { +av_log(avctx, AV_LOG_VERBOSE, + "Use Intel(R) oneVPL to create MFX session with the specified MFX loader\n"); + +loader = *ploader; +} + +while (1) { +/* Enumerate all implementations */ +mfxImplDescription *impl_desc; + +sts = MFXEnumImplementations(loader, impl_idx, + MFX_IMPLCAPS_IMPLDESCSTRUCTURE, + (mfxHDL *)&impl_desc); + +/* Failed to find an available implementation */ +if (sts == MFX_ERR_NOT_FOUND) +break; +else if (sts != MFX_ERR_NONE) { +impl_idx++; +continue; +} + +sts = MFXCreateSession(loader, impl_idx, &session); +MFXDispRelease
[FFmpeg-devel] [PATCH v6 10/10] configure: add --enable-libvpl option
This allows user to build FFmpeg against Intel oneVPL. oneVPL 2.2 is the required minimum version when building Intel oneVPL code. It will fail to run configure script if both libmfx and libvpl are enabled. It is recommended to use oneVPL for new work, even for currently available hardwares [1] Note the preferred child device type is d3d11va for libvpl on Windows. The commands below will use d3d11va if d3d11va is available on Windows. $> ffmpeg -hwaccel qsv -c:v h264_qsv ... $> ffmpeg -qsv_device 0 -hwaccel qsv -c:v h264_qsv ... $> ffmpeg -init_hw_device qsv=qsv:hw_any -hwaccel qsv -c:v h264_qsv ... $> ffmpeg -init_hw_device qsv=qsv:hw_any,child_device=0 -hwaccel qsv -c:v h264_qsv ... User may use child_device_type option to specify child device type to dxva2 or derive a qsv device from a dxva2 device $> ffmpeg -init_hw_device qsv=qsv:hw_any,child_device=0,child_device_type=dxva2 -hwaccel qsv -c:v h264_qsv ... $> ffmpeg -init_hw_device dxva2=d3d9:0 -init_hw_device qsv=qsv@d3d9 -hwaccel qsv -c:v h264_qsv ... [1] https://software.intel.com/content/www/us/en/develop/articles/upgrading-from-msdk-to-onevpl.html --- configure | 27 +-- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/configure b/configure index cc5894dcac..88dc2bda91 100755 --- a/configure +++ b/configure @@ -337,6 +337,7 @@ External library support: --disable-ffnvcodec disable dynamically linked Nvidia code [autodetect] --enable-libdrm enable DRM code (Linux) [no] --enable-libmfx enable Intel MediaSDK (AKA Quick Sync Video) code via libmfx [no] + --enable-libvpl enable Intel oneVPL code via libvpl if libmfx is not used [no] --enable-libnpp enable Nvidia Performance Primitives-based code [no] --enable-mmalenable Broadcom Multi-Media Abstraction Layer (Raspberry Pi) via MMAL [no] --disable-nvdec disable Nvidia video decoding acceleration (via hwaccel) [autodetect] @@ -1898,6 +1899,7 @@ HWACCEL_LIBRARY_NONFREE_LIST=" HWACCEL_LIBRARY_LIST=" $HWACCEL_LIBRARY_NONFREE_LIST libmfx +libvpl mmal omx opencl @@ -6432,22 +6434,35 @@ enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -li enabled libklvanc && require libklvanc libklvanc/vanc.h klvanc_context_create -lklvanc enabled libkvazaar&& require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get enabled liblensfun&& require_pkg_config liblensfun lensfun lensfun.h lf_db_new + +if enabled libmfx && enabled libvpl; then + die "ERROR: can not use libmfx and libvpl together" # While it may appear that require is being used as a pkg-config # fallback for libmfx, it is actually being used to detect a different # installation route altogether. If libmfx is installed via the Intel # Media SDK or Intel Media Server Studio, these don't come with # pkg-config support. Instead, users should make sure that the build # can find the libraries and headers through other means. - -enabled libmfx&& { { check_pkg_config libmfx "libmfx < 2.0" "mfxvideo.h" MFXInit || +elif enabled libmfx; then +{ check_pkg_config libmfx "libmfx < 2.0" "mfxvideo.h" MFXInit || \ # Some old versions of libmfx have the following settings in libmfx.pc: # includedir=/usr/include # Cflags: -I${includedir} # So add -I${includedir}/mfx to CFLAGS - { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit && add_cflags -I${libmfx_incdir}/mfx; } || - { require "libmfx < 2.0" "mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && - warn "build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,\n"\ -"multi-frame encode, user plugins and LA_EXT rate control mode are enabled"; } + { check_pkg_config libmfx "libmfx < 2.0" "mfx/mfxvideo.h" MFXInit && add_cflags -I${libmfx_incdir}/mfx; } || + { require "libmfx < 2.0" "mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } && +warn "build FFmpeg against libmfx 1.x, obsolete features of libmfx such as OPAQUE memory,\n"\ + "multi-frame encode, user plugins and LA_EXT rate control mode are enabled" +elif enabled libvpl; then +# Consider pkg-config only. The name of libmfx is still passed to check_pkg_config function for --enable-libvpl option +# because QSV has dependency on libmfx, we can use the same dependency if using libmfx in this check. The package name +# is extracted from "vpl >= 2.2" +check_pkg_config libmfx "vpl >= 2.2" "mfxvideo.h mfxdispatcher.h" MFXLoad && \ +warn "build FFmpeg against oneVPL 2.2+, OPAQUE memory, multi-frame encode, user plugins\n"\ + "and LA_EXT rate control mode in FFmpeg QSV won't be supported." || +
[FFmpeg-devel] [PATCH v6 06/10] qsvenc: support multi-frame encode when MFX_VERSION < 2.0
Multi-frame encode isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsvenc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index 7a71ffe98f..93af4d1198 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -64,7 +64,7 @@ #define QSV_HAVE_ICQQSV_VERSION_ATLEAST(1, 28) #define QSV_HAVE_VCM0 #define QSV_HAVE_QVBR QSV_VERSION_ATLEAST(1, 28) -#define QSV_HAVE_MF QSV_VERSION_ATLEAST(1, 25) +#define QSV_HAVE_MF QSV_VERSION_ATLEAST(1, 25) && !QSV_ONEVPL #endif #if !QSV_HAVE_LA_DS -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v6 07/10] qsvenc: support MFX_RATECONTROL_LA_EXT when MFX_VERSION < 2.0
MFX_RATECONTROL_LA_EXT isn't supported for MFX_VERSION >= 2.0[1][2]. This is in preparation for oneVPL support [1]: https://spec.oneapi.io/versions/latest/elements/oneVPL/source/appendix/VPL_intel_media_sdk.html#msdk-full-name-feature-removals [2]: https://github.com/oneapi-src/oneVPL --- libavcodec/qsvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 7eaa680ae4..6c6494745f 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -100,7 +100,7 @@ static const struct { #if QSV_HAVE_VCM { MFX_RATECONTROL_VCM, "VCM" }, #endif -#if QSV_VERSION_ATLEAST(1, 10) +#if QSV_VERSION_ATLEAST(1, 10) && !QSV_ONEVPL { MFX_RATECONTROL_LA_EXT, "LA_EXT" }, #endif #if QSV_HAVE_LA_HRD -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] Fix link errors when HAVE_X86ASM is not defined
This fixes the link errors below: LD ffmpeg_g libavfilter/libavfilter.so: undefined reference to `ff_scene_sad_avx2' libavfilter/libavfilter.so: undefined reference to `ff_scene_sad_sse2' collect2: error: ld returned 1 exit status Makefile:108: recipe for target 'ffmpeg_g' failed make: *** [ffmpeg_g] Error 1 Signed-off-by: Haihao Xiang --- libavfilter/x86/scene_sad_init.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/libavfilter/x86/scene_sad_init.c b/libavfilter/x86/scene_sad_init.c index 461fa406d9..7e93ef44d3 100644 --- a/libavfilter/x86/scene_sad_init.c +++ b/libavfilter/x86/scene_sad_init.c @@ -20,6 +20,7 @@ #include "libavutil/x86/cpu.h" #include "libavfilter/scene_sad.h" +#if HAVE_X86ASM #define SCENE_SAD_FUNC(FUNC_NAME, ASM_FUNC_NAME, MMSIZE) \ void ASM_FUNC_NAME(SCENE_SAD_PARAMS); \ \ @@ -50,3 +51,12 @@ ff_scene_sad_fn ff_scene_sad_get_fn_x86(int depth) } return NULL; } + +#else + +ff_scene_sad_fn ff_scene_sad_get_fn_x86(int depth) +{ +return NULL; +} + +#endif \ No newline at end of file -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] lavc/qsv: allow to add more parameter buffers to QSV frame
--- libavcodec/qsv.c | 27 +++ libavcodec/qsv_internal.h | 8 +++- libavcodec/qsvdec.c | 8 +--- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 6e3154e1a3..879e109092 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -821,3 +821,30 @@ int ff_qsv_close_internal_session(QSVSession *qs) #endif return 0; } + +void ff_qsv_frame_add_ext_param (AVCodecContext *avctx, QSVFrame *frame, + mfxExtBuffer * param) +{ +int i; + +for (i = 0; i < frame->num_ext_params; i++) { +mfxExtBuffer *ext_buffer = frame->ext_param[i]; + +if (ext_buffer->BufferId == param->BufferId) { +av_log(avctx, AV_LOG_WARNING, "A buffer with the same type has been " + "added\n"); +return; +} +} + +if (frame->num_ext_params < QSV_MAX_FRAME_EXT_PARAMS) { +frame->ext_param[frame->num_ext_params] = param; +frame->num_ext_params++; +frame->surface.Data.NumExtParam = frame->num_ext_params; +} else { +av_log(avctx, AV_LOG_WARNING, "Ignore this extra buffer because do not " + "have enough space\n"); +} + + +} diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 6b2fbbe252..1d94d429e8 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -52,6 +52,8 @@ #define QSV_MAX_ENC_PAYLOAD 2 // # of mfxEncodeCtrl payloads supported +#define QSV_MAX_FRAME_EXT_PARAMS 4 + #define QSV_VERSION_ATLEAST(MAJOR, MINOR) \ (MFX_VERSION_MAJOR > (MAJOR) || \ MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR)) @@ -74,7 +76,8 @@ typedef struct QSVFrame { mfxFrameSurface1 surface; mfxEncodeCtrl enc_ctrl; mfxExtDecodedFrameInfo dec_info; -mfxExtBuffer *ext_param; +mfxExtBuffer *ext_param[QSV_MAX_FRAME_EXT_PARAMS]; +int num_ext_params; int queued; int used; @@ -142,4 +145,7 @@ int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *session, int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame); +void ff_qsv_frame_add_ext_param(AVCodecContext *avctx, QSVFrame *frame, +mfxExtBuffer *param); + #endif /* AVCODEC_QSV_INTERNAL_H */ diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 5f2e641373..55cf9f35c5 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -366,11 +366,13 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame) frame->surface.Data.MemId = &q->frames_ctx.mids[ret]; } -frame->surface.Data.ExtParam= &frame->ext_param; -frame->surface.Data.NumExtParam = 1; -frame->ext_param= (mfxExtBuffer*)&frame->dec_info; + +frame->surface.Data.ExtParam= frame->ext_param; +frame->surface.Data.NumExtParam = 0; +frame->num_ext_params = 0; frame->dec_info.Header.BufferId = MFX_EXTBUFF_DECODED_FRAME_INFO; frame->dec_info.Header.BufferSz = sizeof(frame->dec_info); +ff_qsv_frame_add_ext_param(avctx, frame, (mfxExtBuffer *)&frame->dec_info); frame->used = 1; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] lavc/qsvdec: export AVFilmGrainParams side data
When AV_CODEC_EXPORT_DATA_FILM_GRAIN is present, AV1 decoder should disable film grain application and export the corresponding side data --- libavcodec/qsv_internal.h | 3 ++ libavcodec/qsvdec.c | 88 +++ 2 files changed, 91 insertions(+) diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 1d94d429e8..754581087d 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -76,6 +76,9 @@ typedef struct QSVFrame { mfxFrameSurface1 surface; mfxEncodeCtrl enc_ctrl; mfxExtDecodedFrameInfo dec_info; +#if QSV_VERSION_ATLEAST(1, 34) +mfxExtAV1FilmGrainParam av1_film_grain_param; +#endif mfxExtBuffer *ext_param[QSV_MAX_FRAME_EXT_PARAMS]; int num_ext_params; diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 55cf9f35c5..e34441fc0b 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -38,6 +38,7 @@ #include "libavutil/pixfmt.h" #include "libavutil/time.h" #include "libavutil/imgutils.h" +#include "libavutil/film_grain_params.h" #include "avcodec.h" #include "internal.h" @@ -334,6 +335,11 @@ static int qsv_decode_header(AVCodecContext *avctx, QSVContext *q, return ff_qsv_print_error(avctx, ret, "Error decoding stream header"); +#if QSV_VERSION_ATLEAST(1, 34) +if (avctx->codec_id == AV_CODEC_ID_AV1) +param->mfx.FilmGrain = (avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) ? 0 : param->mfx.FilmGrain; +#endif + return 0; } @@ -373,6 +379,12 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame) frame->dec_info.Header.BufferId = MFX_EXTBUFF_DECODED_FRAME_INFO; frame->dec_info.Header.BufferSz = sizeof(frame->dec_info); ff_qsv_frame_add_ext_param(avctx, frame, (mfxExtBuffer *)&frame->dec_info); +#if QSV_VERSION_ATLEAST(1, 34) +frame->av1_film_grain_param.Header.BufferId = MFX_EXTBUFF_AV1_FILM_GRAIN_PARAM; +frame->av1_film_grain_param.Header.BufferSz = sizeof(frame->av1_film_grain_param); +frame->av1_film_grain_param.FilmGrainFlags = 0; +ff_qsv_frame_add_ext_param(avctx, frame, (mfxExtBuffer *)&frame->av1_film_grain_param); +#endif frame->used = 1; @@ -443,6 +455,73 @@ static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf) return NULL; } +#if QSV_VERSION_ATLEAST(1, 34) +static int qsv_export_film_grain(AVCodecContext *avctx, mfxExtAV1FilmGrainParam *ext_param, AVFrame *frame) +{ +AVFilmGrainParams *fgp; +AVFilmGrainAOMParams *aom; +int i; + +if (!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_APPLY)) +return 0; + +fgp = av_film_grain_params_create_side_data(frame); + +if (!fgp) +return AVERROR(ENOMEM); + +fgp->type = AV_FILM_GRAIN_PARAMS_AV1; +fgp->seed = ext_param->GrainSeed; +aom = &fgp->codec.aom; + +aom->chroma_scaling_from_luma = !!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_CHROMA_SCALING_FROM_LUMA); +aom->scaling_shift = ext_param->GrainScalingMinus8 + 8; +aom->ar_coeff_lag = ext_param->ArCoeffLag; +aom->ar_coeff_shift = ext_param->ArCoeffShiftMinus6 + 6; +aom->grain_scale_shift = ext_param->GrainScaleShift; +aom->overlap_flag = !!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_OVERLAP); +aom->limit_output_range = !!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_CLIP_TO_RESTRICTED_RANGE); + +aom->num_y_points = ext_param->NumYPoints; + +for (i = 0; i < aom->num_y_points; i++) { +aom->y_points[i][0] = ext_param->PointY[i].Value; +aom->y_points[i][1] = ext_param->PointY[i].Scaling; +} + +aom->num_uv_points[0] = ext_param->NumCbPoints; + +for (i = 0; i < aom->num_uv_points[0]; i++) { +aom->uv_points[0][i][0] = ext_param->PointCb[i].Value; +aom->uv_points[0][i][1] = ext_param->PointCb[i].Scaling; +} + +aom->num_uv_points[1] = ext_param->NumCrPoints; + +for (i = 0; i < aom->num_uv_points[1]; i++) { +aom->uv_points[1][i][0] = ext_param->PointCr[i].Value; +aom->uv_points[1][i][1] = ext_param->PointCr[i].Scaling; +} + +for (i = 0; i < 24; i++) +aom->ar_coeffs_y[i] = ext_param->ArCoeffsYPlus128[i] - 128; + +for (i = 0; i < 25; i++) { +aom->ar_coeffs_uv[0][i] = ext_param->ArCoeffsCbPlus128[i] - 128; +aom->ar_coeffs_uv[1][i] = ext_param->ArCoeffsCrPlus128[i] - 128; +} + +aom->uv_mult[0] = ext_param->CbMult; +aom->uv_mult[1] = ext_param->CrMult; +aom->uv_mult_luma[0] = ext_param->CbLumaMult; +aom->uv_mult_luma[1] = ext_param->CrLumaMult; +aom->uv_offset[0] = ext_param->CbOffset; +aom->uv_offset[1] = ext_param->CrOffset; + +return 0; +} +#endif + static int qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, const AVPacket *avpkt) @@ -546,6 +625,15 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, outsurf = &out_frame->surface; +#i
[FFmpeg-devel] [PATCH 1/3] lavc/qsv: apply AVCodecContext AVOption -threads to QSV
By default the SDK creates a thread for each CPU when creating a mfx session for decoding / encoding, which results in CPU overhead on a multi CPU system. Actually creating 2 threads is a better choice for most cases in practice. This patch allows user to specify the number of threads created for a mfx session via option -threads. If the number is not specified, 2 threads will be created by default. Note the SDK requires at least 2 threads to avoid dead locks[1] [1]https://github.com/Intel-Media-SDK/MediaSDK/blob/master/_studio/mfx_lib/scheduler/linux/src/mfx_scheduler_core_ischeduler.cpp#L90-L93 --- libavcodec/qsv.c | 32 libavcodec/qsvdec.c | 1 + libavcodec/qsvenc_h264.c | 2 +- libavcodec/qsvenc_hevc.c | 2 +- libavcodec/qsvenc_jpeg.c | 1 + libavcodec/qsvenc_mpeg2.c | 2 +- libavcodec/qsvenc_vp9.c | 2 +- 7 files changed, 38 insertions(+), 4 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 6e3154e1a3..c725883c5c 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -390,11 +390,27 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, const char *desc; int ret; +#if QSV_VERSION_ATLEAST(1, 15) +mfxExtBuffer *ext_params[1]; +mfxExtThreadsParam thread_param; +#endif + #if QSV_VERSION_ATLEAST(1, 16) init_par.GPUCopy= gpu_copy; #endif init_par.Implementation = impl; init_par.Version= ver; + +#if QSV_VERSION_ATLEAST(1, 15) +memset(&thread_param, 0, sizeof(thread_param)); +thread_param.Header.BufferId = MFX_EXTBUFF_THREADS_PARAM; +thread_param.Header.BufferSz = sizeof(thread_param); +thread_param.NumThread = FFMAX(2, avctx->thread_count); +ext_params[0]= (mfxExtBuffer *)&thread_param; +init_par.ExtParam= (mfxExtBuffer **)&ext_params; +init_par.NumExtParam = 1; +#endif + ret = MFXInitEx(init_par, &qs->session); if (ret < 0) return ff_qsv_print_error(avctx, ret, @@ -709,6 +725,11 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession, int i, ret; +#if QSV_VERSION_ATLEAST(1, 15) +mfxExtBuffer *ext_params[1]; +mfxExtThreadsParam thread_param; +#endif + err = MFXQueryIMPL(parent_session, &impl); if (err == MFX_ERR_NONE) err = MFXQueryVersion(parent_session, &ver); @@ -734,6 +755,17 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession, #endif init_par.Implementation = impl; init_par.Version= ver; + +#if QSV_VERSION_ATLEAST(1, 15) +memset(&thread_param, 0, sizeof(thread_param)); +thread_param.Header.BufferId = MFX_EXTBUFF_THREADS_PARAM; +thread_param.Header.BufferSz = sizeof(thread_param); +thread_param.NumThread = FFMAX(2, avctx->thread_count); +ext_params[0]= (mfxExtBuffer *)&thread_param; +init_par.ExtParam= (mfxExtBuffer **)&ext_params; +init_par.NumExtParam = 1; +#endif + err = MFXInitEx(init_par, &session); if (err != MFX_ERR_NONE) return ff_qsv_print_error(avctx, err, diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 5f2e641373..d3365b6f3b 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -846,6 +846,7 @@ AVCodec ff_##x##_qsv_decoder = { \ .close = qsv_decode_close, \ .bsfs = bsf_name, \ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID, \ +.caps_internal = FF_CODEC_CAP_AUTO_THREADS, \ .priv_class = &x##_qsv_class, \ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \ AV_PIX_FMT_P010, \ diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c index ddafc45ec3..fb587ff87c 100644 --- a/libavcodec/qsvenc_h264.c +++ b/libavcodec/qsvenc_h264.c @@ -196,7 +196,7 @@ AVCodec ff_h264_qsv_encoder = { AV_PIX_FMT_NONE }, .priv_class = &class, .defaults = qsv_enc_defaults, -.caps_internal = FF_CODEC_CAP_INIT_CLEANUP, +.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS, .wrapper_name = "qsv", .hw_configs = ff_qsv_enc_hw_configs, }; diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index 347f30655e..a9e5906309 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -289,7 +289,7 @@ AVCodec ff_hevc_qsv_encoder = { AV_PIX_FMT_NONE }, .priv_class = &class, .defaults = qsv_enc_defaults, -.caps_internal = FF_CODEC_CAP_INIT_CLEANUP, +.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS, .wrapper_name = "qsv", .hw_configs = ff_qsv_enc_hw_configs, }; diff --git a/libavcodec/qsvenc_jpeg.c b/libavcodec/qsvenc_jpeg.c index f76af948
[FFmpeg-devel] [PATCH 2/3] lavu/hwcontext_qsv: limit the number of threads for QSV HW device to 2
The session created for QSV HW device will be used as parent session only, so we needn't create more threads for this session --- libavutil/hwcontext_qsv.c | 24 ++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 30b0d81f84..84cf5015ff 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -1142,6 +1142,12 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, mfxHandleType handle_type; mfxStatus err; int ret; +mfxInitParam init_par = { MFX_IMPL_AUTO_ANY }; + +#if QSV_VERSION_ATLEAST(1, 15) +mfxExtBuffer *ext_params[1]; +mfxExtThreadsParam thread_param; +#endif switch (child_device_ctx->type) { #if CONFIG_VAAPI @@ -1167,7 +1173,20 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, goto fail; } -err = MFXInit(implementation, &ver, &hwctx->session); +init_par.Implementation = implementation; +init_par.Version= ver; + +#if QSV_VERSION_ATLEAST(1, 15) +memset(&thread_param, 0, sizeof(thread_param)); +thread_param.Header.BufferId = MFX_EXTBUFF_THREADS_PARAM; +thread_param.Header.BufferSz = sizeof(thread_param); +thread_param.NumThread = 2; +ext_params[0]= (mfxExtBuffer *)&thread_param; +init_par.ExtParam= (mfxExtBuffer **)&ext_params; +init_par.NumExtParam = 1; +#endif + +err = MFXInitEx(init_par, &hwctx->session); if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: " "%d.\n", err); @@ -1188,7 +1207,8 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, MFXClose(hwctx->session); -err = MFXInit(implementation, &ver, &hwctx->session); +init_par.Version = ver; +err = MFXInitEx(init_par, &hwctx->session); if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: %d.\n", err); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] lavu/hwcontext_qsv: limit the number of threads used for hwupload & hwdownload to 2
The session for hwupload & hwdownload is used to copy data between system and video memory, 2 threads are sufficient for the copy in the SDK. --- libavutil/hwcontext_qsv.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 84cf5015ff..5dbe2b1701 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -456,8 +456,25 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx, mfxVideoParam par; mfxStatus err; +mfxInitParam init_par = { MFX_IMPL_AUTO_ANY }; -err = MFXInit(device_priv->impl, &device_priv->ver, session); +#if QSV_VERSION_ATLEAST(1, 15) +mfxExtBuffer *ext_params[1]; +mfxExtThreadsParam thread_param; + +memset(&thread_param, 0, sizeof(thread_param)); +thread_param.Header.BufferId = MFX_EXTBUFF_THREADS_PARAM; +thread_param.Header.BufferSz = sizeof(thread_param); +thread_param.NumThread = 2; +ext_params[0]= (mfxExtBuffer *)&thread_param; +init_par.ExtParam= (mfxExtBuffer **)&ext_params; +init_par.NumExtParam = 1; +#endif + +init_par.Implementation = device_priv->impl; +init_par.Version = device_priv->ver; + +err = MFXInitEx(init_par, session); if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_ERROR, "Error initializing an internal session\n"); return AVERROR_UNKNOWN; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] hwcontext_vaapi: the first parameter is the AVHWFramesContext for dst
vaapi_map_from_drm() is the implementation of map_to when src format is AV_PIX_FMT_DRM_PRIME, and the first parameter of map_to is the AVHWFramesContext for dst Signed-off-by: Haihao Xiang --- libavutil/hwcontext_vaapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index b31cf95850..a378bcd12a 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -999,11 +999,11 @@ static void vaapi_unmap_from_drm(AVHWFramesContext *dst_fc, vaDestroySurfaces(dst_dev->display, &surface_id, 1); } -static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst, +static int vaapi_map_from_drm(AVHWFramesContext *dst_fc, AVFrame *dst, const AVFrame *src, int flags) { -AVHWFramesContext *dst_fc = -(AVHWFramesContext*)dst->hw_frames_ctx->data; +AVHWFramesContext *src_fc = +(AVHWFramesContext*)src->hw_frames_ctx->data; AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; const AVDRMFrameDescriptor *desc; const VAAPIFormatDescriptor *format_desc; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] hwcontext_vaapi: try VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 firstly when importing a DMABuf
User should provide the modifier when importing a DMABuf if this DMABuf has modifier. Signed-off-by: Haihao Xiang --- libavutil/hwcontext_vaapi.c | 137 +--- 1 file changed, 126 insertions(+), 11 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index a378bcd12a..514bb07a20 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -999,8 +999,9 @@ static void vaapi_unmap_from_drm(AVHWFramesContext *dst_fc, vaDestroySurfaces(dst_dev->display, &surface_id, 1); } -static int vaapi_map_from_drm(AVHWFramesContext *dst_fc, AVFrame *dst, - const AVFrame *src, int flags) +static VASurfaceID vaapi_get_surface_from_drm_prime(AVHWFramesContext *dst_fc, +AVFrame *dst, +const AVFrame *src) { AVHWFramesContext *src_fc = (AVHWFramesContext*)src->hw_frames_ctx->data; @@ -1010,7 +1011,7 @@ static int vaapi_map_from_drm(AVHWFramesContext *dst_fc, AVFrame *dst, VASurfaceID surface_id; VAStatus vas; uint32_t va_fourcc; -int err, i, j, k; +int i, j, k; unsigned long buffer_handle; VASurfaceAttribExternalBuffers buffer_desc; @@ -1030,13 +1031,6 @@ static int vaapi_map_from_drm(AVHWFramesContext *dst_fc, AVFrame *dst, }; desc = (AVDRMFrameDescriptor*)src->data[0]; - -if (desc->nb_objects != 1) { -av_log(dst_fc, AV_LOG_ERROR, "VAAPI can only map frames " - "made from a single DRM object.\n"); -return AVERROR(EINVAL); -} - va_fourcc = 0; for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { if (desc->nb_layers != vaapi_drm_format_map[i].nb_layer_formats) @@ -1092,9 +1086,130 @@ static int vaapi_map_from_drm(AVHWFramesContext *dst_fc, AVFrame *dst, src->width, src->height, &surface_id, 1, attrs, FF_ARRAY_ELEMS(attrs)); + +if (vas != VA_STATUS_SUCCESS) { +av_log(dst_fc, AV_LOG_DEBUG, "Failed to create surface from DRM_PRIME " + "object: %d (%s).\n", vas, vaErrorStr(vas)); +return VA_INVALID_ID; +} + +return surface_id; +} + +static VASurfaceID vaapi_get_surface_from_drm_prime2(AVHWFramesContext *dst_fc, + AVFrame *dst, + const AVFrame *src) +{ +AVHWFramesContext *src_fc = +(AVHWFramesContext*)src->hw_frames_ctx->data; +AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; +const AVDRMFrameDescriptor *desc; +const VAAPIFormatDescriptor *format_desc; +VASurfaceID surface_id; +VAStatus vas; +uint32_t va_fourcc; +int i, j; + +VADRMPRIMESurfaceDescriptor surface_desc; +VASurfaceAttrib attrs[2] = { +{ +.type = VASurfaceAttribMemoryType, +.flags = VA_SURFACE_ATTRIB_SETTABLE, +.value.type= VAGenericValueTypeInteger, +.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, +}, +{ +.type = VASurfaceAttribExternalBufferDescriptor, +.flags = VA_SURFACE_ATTRIB_SETTABLE, +.value.type= VAGenericValueTypePointer, +.value.value.p = &surface_desc, +} +}; + +desc = (AVDRMFrameDescriptor*)src->data[0]; +va_fourcc = 0; +for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { +if (desc->nb_layers != vaapi_drm_format_map[i].nb_layer_formats) +continue; +for (j = 0; j < desc->nb_layers; j++) { +if (desc->layers[j].format != +vaapi_drm_format_map[i].layer_formats[j]) +break; +} +if (j != desc->nb_layers) +continue; +va_fourcc = vaapi_drm_format_map[i].va_fourcc; +break; +} +if (!va_fourcc) { +av_log(dst_fc, AV_LOG_ERROR, "DRM format not supported " + "by VAAPI.\n"); +return AVERROR(EINVAL); +} + +av_log(dst_fc, AV_LOG_DEBUG, "Map DRM object %d to VAAPI as " + "%08x.\n", desc->objects[0].fd, va_fourcc); + +format_desc = vaapi_format_from_fourcc(va_fourcc); +av_assert0(format_desc && !format_desc->chroma_planes_swapped); + +surface_desc.fourcc = va_fourcc; +surface_desc.width = src_fc->width; +surface_desc.height = src_fc->height; +surface_desc.num_objects = 1; +surface_desc.objects[0].fd = desc->objects[0].fd; +surface_desc.objects[0].size = desc->objects[0].size; +surface_desc.objects[0].drm_format_modifier = desc->objects[0].format_modifier; +surface_desc.num_layers = d
[FFmpeg-devel] [PATCH 1/2] lavc/qsvenc_hevc: allow user set more coding options
The SDK supports NalHrdConformance, RecoveryPointSEI and AUDelimiter for hevc encoder, so we may allow user to set these coding options like what we did for h264_qsv encoder. '-strict xxx' to turn on / off NalHrdConformance '-recovery_point_sei xxx' to turn on / off RecoveryPointSEI '-aud xxx' to turn on / off AUDelimiter Signed-off-by: Haihao Xiang --- libavcodec/qsvenc.c | 15 --- libavcodec/qsvenc_hevc.c | 2 ++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 566a5c8552..aeb010e456 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -290,6 +290,10 @@ static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q, "NalHrdConformance: %s; SingleSeiNalUnit: %s; VuiVclHrdParameters: %s VuiNalHrdParameters: %s\n", print_threestate(co->NalHrdConformance), print_threestate(co->SingleSeiNalUnit), print_threestate(co->VuiVclHrdParameters), print_threestate(co->VuiNalHrdParameters)); +} else if (avctx->codec_id == AV_CODEC_ID_HEVC) { +av_log(avctx, AV_LOG_VERBOSE, + "NalHrdConformance: %s; VuiNalHrdParameters: %s\n", + print_threestate(co->NalHrdConformance), print_threestate(co->VuiNalHrdParameters)); } av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32"; FrameRateExtN: %"PRIu32" \n", @@ -676,15 +680,20 @@ FF_ENABLE_DEPRECATION_WARNINGS q->extco.CAVLC = q->cavlc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN; +if (q->single_sei_nal_unit >= 0) +q->extco.SingleSeiNalUnit = q->single_sei_nal_unit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; + +q->extco.MaxDecFrameBuffering = q->max_dec_frame_buffering; +} + +if (avctx->codec_id == AV_CODEC_ID_H264 || +avctx->codec_id == AV_CODEC_ID_HEVC) { if (avctx->strict_std_compliance != FF_COMPLIANCE_NORMAL) q->extco.NalHrdConformance = avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; -if (q->single_sei_nal_unit >= 0) -q->extco.SingleSeiNalUnit = q->single_sei_nal_unit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; if (q->recovery_point_sei >= 0) q->extco.RecoveryPointSEI = q->recovery_point_sei ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; -q->extco.MaxDecFrameBuffering = q->max_dec_frame_buffering; q->extco.AUDelimiter = q->aud ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; } diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index 347f30655e..aa02361d1d 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -246,6 +246,8 @@ static const AVOption options[] = { { "tile_cols", "Number of columns for tiled encoding", OFFSET(qsv.tile_cols),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE }, { "tile_rows", "Number of rows for tiled encoding", OFFSET(qsv.tile_rows),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE }, +{ "recovery_point_sei", "Insert recovery point SEI messages", OFFSET(qsv.recovery_point_sei), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, +{ "aud", "Insert the Access Unit Delimiter NAL", OFFSET(qsv.aud), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE}, { NULL }, }; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] lavf/qsvenc: '0' is not a valid value for GopOptFlag
The accepted values for GopOptFlag are MFX_GOP_CLOSED (1) and MFX_GOP_STRICT (2). Signed-off-by: Haihao Xiang --- libavcodec/qsvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index aeb010e456..684c8089eb 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -531,7 +531,7 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size); q->param.mfx.GopRefDist = FFMAX(-1, avctx->max_b_frames) + 1; q->param.mfx.GopOptFlag = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ? - MFX_GOP_CLOSED : 0; + MFX_GOP_CLOSED : MFX_GOP_STRICT; q->param.mfx.IdrInterval= q->idr_interval; q->param.mfx.NumSlice = avctx->slices; q->param.mfx.NumRefFrame= FFMAX(0, avctx->refs); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 00/22] clean-up QSV filters
This patchset clean up scale_qsv and deinterlace_qsv filters, and take the two filters as the special cases of vpp_qsv, so vf_scale_qsv.c and vf_deinterlace_qsv.c can be deleted from FFmpeg. In addition, a few small features are added in this patchset. Haihao Xiang (22): lavf/qsv: use QSVVPPContext as base context in vf_vpp_qsv/vf_overlay_qsv lavf/scale_qsv: simplify scale_qsv filter lavf/scale_qsv: don't need variables for constants in FFmpeg lavf/vpp_qsv: add "a", "dar" and "sar" variables lavf/vpp_qsv: handle NULL pointer when evaluating an expression lavf/vpp_qsv: allow special values for the output dimensions lavf/vpp_qsv: factorize extra MFX configuration lavf/vpp_qsv: pass scaling mode to the SDK lavf/vpp_qsv: add vpp_preinit callback lavf/scale_qsv: re-use VPPContext for scale_qsv filter lavf/vpp_qsv: factor common QSV filter definition lavf/scale_qsv: add new options for scale_qsv filter lavf/scale_qsv: add more input / output pixel formats lavf/vpp_qsv: double the framerate for deinterlacing lavf/qsvvpp: avoid overriding the returned value lavf/qsvvpp: set PTS for output frame lavf/vpp_qsv: check output format string against NULL pointer lavf/deinterlace_qsv: simplify deinterlace_qsv filter lavf/deinterlace_qsv: re-use VPPContext for deinterlace_qsv filter lavf/deinterlace_qsv: add async_depth option lavf/deinterlace_qsv: add more input / output pixel formats lavf/vpp_qsv: allow user to set scaling mode for vpp_qsv filter libavfilter/Makefile | 4 +- libavfilter/qsvvpp.c | 57 ++- libavfilter/qsvvpp.h | 11 +- libavfilter/vf_deinterlace_qsv.c | 611 --- libavfilter/vf_overlay_qsv.c | 11 +- libavfilter/vf_scale_qsv.c | 685 --- libavfilter/vf_vpp_qsv.c | 474 + 7 files changed, 353 insertions(+), 1500 deletions(-) delete mode 100644 libavfilter/vf_deinterlace_qsv.c delete mode 100644 libavfilter/vf_scale_qsv.c -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 01/22] lavf/qsv: use QSVVPPContext as base context in vf_vpp_qsv/vf_overlay_qsv
The same members between QSVVPPContext and VPPContext are removed from VPPContext, and async_depth is moved from QSVVPPParam to QSVVPPContext so that all QSV filters using QSVVPPContext may support async depth. In addition we may use QSVVPPContext as base context in other QSV filters in the future. --- libavfilter/qsvvpp.c | 25 - libavfilter/qsvvpp.h | 8 libavfilter/vf_overlay_qsv.c | 11 +-- libavfilter/vf_vpp_qsv.c | 34 +- 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 4768f6208b..5b0b30e23c 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -647,15 +647,11 @@ static unsigned int qsv_fifo_size(const AVFifoBuffer* fifo) return av_fifo_size(fifo)/qsv_fifo_item_size(); } -int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *param) +int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param) { int i; int ret; -QSVVPPContext *s; - -s = av_mallocz(sizeof(*s)); -if (!s) -return AVERROR(ENOMEM); +QSVVPPContext *s = avctx->priv; s->filter_frame = param->filter_frame; if (!s->filter_frame) @@ -722,14 +718,13 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p s->got_frame = 0; /** keep fifo size at least 1. Even when async_depth is 0, fifo is used. */ -s->async_fifo = av_fifo_alloc((param->async_depth + 1) * qsv_fifo_item_size()); -s->async_depth = param->async_depth; +s->async_fifo = av_fifo_alloc((s->async_depth + 1) * qsv_fifo_item_size()); if (!s->async_fifo) { ret = AVERROR(ENOMEM); goto failed; } -s->vpp_param.AsyncDepth = param->async_depth; +s->vpp_param.AsyncDepth = s->async_depth; if (IS_SYSTEM_MEMORY(s->in_mem_mode)) s->vpp_param.IOPattern |= MFX_IOPATTERN_IN_SYSTEM_MEMORY; @@ -756,25 +751,22 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p } else if (ret > 0) ff_qsvvpp_print_warning(avctx, ret, "Warning When creating qsvvpp"); -*vpp = s; return 0; failed: -ff_qsvvpp_free(&s); +ff_qsvvpp_close(avctx); return ret; } -int ff_qsvvpp_free(QSVVPPContext **vpp) +int ff_qsvvpp_close(AVFilterContext *avctx) { -QSVVPPContext *s = *vpp; - -if (!s) -return 0; +QSVVPPContext *s = avctx->priv; if (s->session) { MFXVideoVPP_Close(s->session); MFXClose(s->session); +s->session = NULL; } /* release all the resources */ @@ -785,7 +777,6 @@ int ff_qsvvpp_free(QSVVPPContext **vpp) av_freep(&s->ext_buffers); av_freep(&s->frame_infos); av_fifo_free(s->async_fifo); -av_freep(vpp); return 0; } diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index e0f4c8f5bb..b6fe0d3fa7 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -48,6 +48,8 @@ typedef struct QSVFrame { } QSVFrame; typedef struct QSVVPPContext { +const AVClass *class; + mfxSession session; int (*filter_frame) (AVFilterLink *outlink, AVFrame *frame); /**< callback */ enum AVPixelFormat out_sw_format; /**< Real output format */ @@ -95,15 +97,13 @@ typedef struct QSVVPPParam { /* Crop information for each input, if needed */ int num_crop; QSVVPPCrop *crop; - - int async_depth; } QSVVPPParam; /* create and initialize the QSV session */ -int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *param); +int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param); /* release the resources (eg.surfaces) */ -int ff_qsvvpp_free(QSVVPPContext **vpp); +int ff_qsvvpp_close(AVFilterContext *avctx); /* vpp filter frame and call the cb if needed */ int ff_qsvvpp_filter_frame(QSVVPPContext *vpp, AVFilterLink *inlink, AVFrame *frame); diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c index 7a4afd77d4..0b978d6528 100644 --- a/libavfilter/vf_overlay_qsv.c +++ b/libavfilter/vf_overlay_qsv.c @@ -58,10 +58,9 @@ enum var_name { }; typedef struct QSVOverlayContext { -const AVClass *class; +QSVVPPContext qsv; FFFrameSync fs; -QSVVPPContext *qsv; QSVVPPParamqsv_param; mfxExtVPPComposite comp_conf; double var_values[VAR_VARS_NB]; @@ -231,14 +230,14 @@ static int config_overlay_input(AVFilterLink *inlink) static int process_frame(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; -QSVOverlayContext *s = fs->opaque; +QSVVPPContext*qsv = fs->opaque; AVFrame*frame = NULL; int ret = 0, i; for (i = 0; i < ctx->nb_inputs; i++) { ret = ff_framesync_get_frame(fs, i, &frame, 0); if (ret == 0) -ret = ff_qsvvpp_filter_frame(s->qsv, ctx->inputs[i], frame); +
[FFmpeg-devel] [PATCH 02/22] lavf/scale_qsv: simplify scale_qsv filter
Use QSVVPPContext as a base context of QSVScaleContext, hence we may re-use functions defined for QSVVPPContext to manage MFX session for scale_qsv filter too. Because system memory is taken into account in QSVVVPPContext, we may add support for non-QSV pixel formats in the future --- libavfilter/vf_scale_qsv.c | 456 + 1 file changed, 57 insertions(+), 399 deletions(-) diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index 189223a58a..77a782aa58 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -72,35 +72,13 @@ enum var_name { #define QSV_HAVE_SCALING_CONFIG QSV_VERSION_ATLEAST(1, 19) typedef struct QSVScaleContext { -const AVClass *class; - -/* a clone of the main session, used internally for scaling */ -mfxSession session; - -mfxMemId *mem_ids_in; -int nb_mem_ids_in; - -mfxMemId *mem_ids_out; -int nb_mem_ids_out; - -mfxFrameSurface1 **surface_ptrs_in; -int nb_surface_ptrs_in; - -mfxFrameSurface1 **surface_ptrs_out; -int nb_surface_ptrs_out; - -mfxExtOpaqueSurfaceAlloc opaque_alloc; +QSVVPPContext qsv; #if QSV_HAVE_SCALING_CONFIG mfxExtVPPScaling scale_conf; #endif int mode; -mfxExtBuffer *ext_buffers[1 + QSV_HAVE_SCALING_CONFIG]; -int num_ext_buf; - -int shift_width, shift_height; - /** * New dimensions. Special values are: * 0 = original width/height @@ -137,22 +115,7 @@ static av_cold int qsvscale_init(AVFilterContext *ctx) static av_cold void qsvscale_uninit(AVFilterContext *ctx) { -QSVScaleContext *s = ctx->priv; - -if (s->session) { -MFXClose(s->session); -s->session = NULL; -} - -av_freep(&s->mem_ids_in); -av_freep(&s->mem_ids_out); -s->nb_mem_ids_in = 0; -s->nb_mem_ids_out = 0; - -av_freep(&s->surface_ptrs_in); -av_freep(&s->surface_ptrs_out); -s->nb_surface_ptrs_in = 0; -s->nb_surface_ptrs_out = 0; +ff_qsvvpp_close(ctx); } static int qsvscale_query_formats(AVFilterContext *ctx) @@ -169,313 +132,20 @@ static int qsvscale_query_formats(AVFilterContext *ctx) return 0; } -static int init_out_pool(AVFilterContext *ctx, - int out_width, int out_height) -{ -QSVScaleContext *s = ctx->priv; -AVFilterLink *outlink = ctx->outputs[0]; - -AVHWFramesContext *in_frames_ctx; -AVHWFramesContext *out_frames_ctx; -AVQSVFramesContext *in_frames_hwctx; -AVQSVFramesContext *out_frames_hwctx; -enum AVPixelFormat in_format; -enum AVPixelFormat out_format; -int i, ret; - -/* check that we have a hw context */ -if (!ctx->inputs[0]->hw_frames_ctx) { -av_log(ctx, AV_LOG_ERROR, "No hw context provided on input\n"); -return AVERROR(EINVAL); -} -in_frames_ctx = (AVHWFramesContext*)ctx->inputs[0]->hw_frames_ctx->data; -in_frames_hwctx = in_frames_ctx->hwctx; - -in_format = in_frames_ctx->sw_format; -out_format= (s->format == AV_PIX_FMT_NONE) ? in_format : s->format; - -outlink->hw_frames_ctx = av_hwframe_ctx_alloc(in_frames_ctx->device_ref); -if (!outlink->hw_frames_ctx) -return AVERROR(ENOMEM); -out_frames_ctx = (AVHWFramesContext*)outlink->hw_frames_ctx->data; -out_frames_hwctx = out_frames_ctx->hwctx; - -out_frames_ctx->format= AV_PIX_FMT_QSV; -out_frames_ctx->width = FFALIGN(out_width, 16); -out_frames_ctx->height= FFALIGN(out_height, 16); -out_frames_ctx->sw_format = out_format; -out_frames_ctx->initial_pool_size = 4; - -out_frames_hwctx->frame_type = in_frames_hwctx->frame_type; - -ret = ff_filter_init_hw_frames(ctx, outlink, 32); -if (ret < 0) -return ret; - -ret = av_hwframe_ctx_init(outlink->hw_frames_ctx); -if (ret < 0) -return ret; - -for (i = 0; i < out_frames_hwctx->nb_surfaces; i++) { -mfxFrameInfo *info = &out_frames_hwctx->surfaces[i].Info; -info->CropW = out_width; -info->CropH = out_height; -} - -return 0; -} - -static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, - mfxFrameAllocResponse *resp) -{ -AVFilterContext *ctx = pthis; -QSVScaleContext *s = ctx->priv; - -if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || -!(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || -!(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) -return MFX_ERR_UNSUPPORTED; - -if (req->Type & MFX_MEMTYPE_FROM_VPPIN) { -resp->mids = s->mem_ids_in; -resp->NumFrameActual = s->nb_mem_ids_in; -} else { -resp->mids = s->mem_ids_out; -resp->NumFrameActual = s->nb_mem_ids_out; -} - -return MFX_ERR_NONE; -} - -static mfxStatus frame_free(mfxHDL pthis, mfx
[FFmpeg-devel] [PATCH 04/22] lavf/vpp_qsv: add "a", "dar" and "sar" variables
Also fix the coding style for VAR index. This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 29 +++-- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 72df8a8373..e7d2c9385a 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -141,18 +141,22 @@ static const char *const var_names[] = { "ch", "cx", "cy", +"a", "dar", +"sar", NULL }; enum var_name { -VAR_iW, VAR_IN_W, -VAR_iH, VAR_IN_H, -VAR_oW, VAR_OUT_W, VAR_W, -VAR_oH, VAR_OUT_H, VAR_H, +VAR_IW, VAR_IN_W, +VAR_IH, VAR_IN_H, +VAR_OW, VAR_OUT_W, VAR_W, +VAR_OH, VAR_OUT_H, VAR_H, CW, CH, CX, CY, +VAR_A, VAR_DAR, +VAR_SAR, VAR_VARS_NB }; @@ -184,12 +188,17 @@ static int eval_expr(AVFilterContext *ctx) PASS_EXPR(cx_expr, vpp->cx); PASS_EXPR(cy_expr, vpp->cy); -var_values[VAR_iW] = +var_values[VAR_IW] = var_values[VAR_IN_W] = ctx->inputs[0]->w; -var_values[VAR_iH] = +var_values[VAR_IH] = var_values[VAR_IN_H] = ctx->inputs[0]->h; +var_values[VAR_A] = (double)var_values[VAR_IN_W] / var_values[VAR_IN_H]; +var_values[VAR_SAR] = ctx->inputs[0]->sample_aspect_ratio.num ? +(double)ctx->inputs[0]->sample_aspect_ratio.num / ctx->inputs[0]->sample_aspect_ratio.den : 1; +var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; + /* crop params */ CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h); @@ -198,15 +207,15 @@ static int eval_expr(AVFilterContext *ctx) CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); CALC_EXPR(w_expr, -var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W], +var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], vpp->out_width); CALC_EXPR(h_expr, -var_values[VAR_OUT_H] = var_values[VAR_oH] = var_values[VAR_H], +var_values[VAR_OUT_H] = var_values[VAR_OH] = var_values[VAR_H], vpp->out_height); /* calc again in case ow is relative to oh */ CALC_EXPR(w_expr, -var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W], +var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], vpp->out_width); @@ -216,7 +225,7 @@ static int eval_expr(AVFilterContext *ctx) /* calc again in case cx is relative to cy */ CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x); -if ((vpp->crop_w != var_values[VAR_iW]) || (vpp->crop_h != var_values[VAR_iH])) +if ((vpp->crop_w != var_values[VAR_IW]) || (vpp->crop_h != var_values[VAR_IH])) vpp->use_crop = 1; release: -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 03/22] lavf/scale_qsv: don't need variables for constants in FFmpeg
PI, PHI and E are defined in FFmpeg --- libavfilter/vf_scale_qsv.c | 9 - 1 file changed, 9 deletions(-) diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index 77a782aa58..f8e937e40e 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -44,9 +44,6 @@ #include "video.h" static const char *const var_names[] = { -"PI", -"PHI", -"E", "in_w", "iw", "in_h", "ih", "out_w", "ow", @@ -57,9 +54,6 @@ static const char *const var_names[] = { }; enum var_name { -VAR_PI, -VAR_PHI, -VAR_E, VAR_IN_W, VAR_IW, VAR_IN_H, VAR_IH, VAR_OUT_W, VAR_OW, @@ -147,9 +141,6 @@ static int qsvscale_config_props(AVFilterLink *outlink) int ret; enum AVPixelFormat in_format; -var_values[VAR_PI]= M_PI; -var_values[VAR_PHI] = M_PHI; -var_values[VAR_E] = M_E; var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w; var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 05/22] lavf/vpp_qsv: handle NULL pointer when evaluating an expression
This is in preparation for re-using VPPContext but with a different option array for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 36 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index e7d2c9385a..adcfd0484d 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -163,14 +163,19 @@ enum var_name { static int eval_expr(AVFilterContext *ctx) { #define PASS_EXPR(e, s) {\ -ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \ -if (ret < 0) {\ -av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s);\ -goto release;\ +if (s) {\ +ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \ +if (ret < 0) { \ +av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s); \ +goto release; \ +} \ }\ } -#define CALC_EXPR(e, v, i) {\ -i = v = av_expr_eval(e, var_values, NULL); \ +#define CALC_EXPR(e, v, i, d) {\ +if (e)\ +i = v = av_expr_eval(e, var_values, NULL); \ +else\ +i = v = d;\ } VPPContext *vpp = ctx->priv; double var_values[VAR_VARS_NB] = { NAN }; @@ -200,30 +205,29 @@ static int eval_expr(AVFilterContext *ctx) var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; /* crop params */ -CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); -CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h); +CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w, var_values[VAR_IW]); +CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h, var_values[VAR_IH]); /* calc again in case cw is relative to ch */ -CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); +CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w, var_values[VAR_IW]); CALC_EXPR(w_expr, var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], -vpp->out_width); +vpp->out_width, var_values[CW]); CALC_EXPR(h_expr, var_values[VAR_OUT_H] = var_values[VAR_OH] = var_values[VAR_H], -vpp->out_height); +vpp->out_height, var_values[CH]); /* calc again in case ow is relative to oh */ CALC_EXPR(w_expr, var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], -vpp->out_width); +vpp->out_width, var_values[CW]); - -CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x); -CALC_EXPR(cy_expr, var_values[CY], vpp->crop_y); +CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x, (var_values[VAR_IW] - var_values[VAR_OW]) / 2); +CALC_EXPR(cy_expr, var_values[CY], vpp->crop_y, (var_values[VAR_IH] - var_values[VAR_OH]) / 2); /* calc again in case cx is relative to cy */ -CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x); +CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x, (var_values[VAR_IW] - var_values[VAR_OW]) / 2); if ((vpp->crop_w != var_values[VAR_IW]) || (vpp->crop_h != var_values[VAR_IH])) vpp->use_crop = 1; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 09/22] lavf/vpp_qsv: add vpp_preinit callback
Set the expected default value for options in this callback, hence we have the right values even if these options are not included in the option arrray. This is in preparation for re-using VPPContext but with a different option array for other QSV filters --- libavfilter/vf_vpp_qsv.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index fd45c4f352..fb950001c0 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -256,6 +256,19 @@ release: return ret; } +static av_cold int vpp_preinit(AVFilterContext *ctx) +{ +VPPContext *vpp = ctx->priv; +/* For AV_OPT_TYPE_STRING options, NULL is handled in other way so + * we needn't set default value here + */ +vpp->saturation = 1.0; +vpp->contrast = 1.0; +vpp->transpose = -1; + +return 0; +} + static av_cold int vpp_init(AVFilterContext *ctx) { VPPContext *vpp = ctx->priv; @@ -637,6 +650,7 @@ const AVFilter ff_vf_vpp_qsv = { .description = NULL_IF_CONFIG_SMALL("Quick Sync Video VPP."), .priv_size = sizeof(VPPContext), .query_formats = query_formats, +.preinit = vpp_preinit, .init = vpp_init, .uninit= vpp_uninit, .inputs= vpp_inputs, -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 07/22] lavf/vpp_qsv: factorize extra MFX configuration
This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 78 +--- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 7afbb3c983..c9a7b0ceb9 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -373,53 +373,44 @@ static int config_output(AVFilterLink *outlink) param.crop = &crop; } -if (vpp->deinterlace) { -memset(&vpp->deinterlace_conf, 0, sizeof(mfxExtVPPDeinterlacing)); -vpp->deinterlace_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING; -vpp->deinterlace_conf.Header.BufferSz = sizeof(mfxExtVPPDeinterlacing); -vpp->deinterlace_conf.Mode = vpp->deinterlace == 1 ? - MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED; +#define INIT_MFX_EXTBUF(extbuf, id) do { \ +memset(&vpp->extbuf, 0, sizeof(vpp->extbuf)); \ +vpp->extbuf.Header.BufferId = id; \ +vpp->extbuf.Header.BufferSz = sizeof(vpp->extbuf); \ +param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->extbuf; \ +} while (0) + +#define SET_MFX_PARAM_FIELD(extbuf, field, value) do { \ +vpp->extbuf.field = value; \ +} while (0) -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->deinterlace_conf; +if (vpp->deinterlace) { +INIT_MFX_EXTBUF(deinterlace_conf, MFX_EXTBUFF_VPP_DEINTERLACING); +SET_MFX_PARAM_FIELD(deinterlace_conf, Mode, (vpp->deinterlace == 1 ? +MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED)); } if (vpp->use_frc) { -memset(&vpp->frc_conf, 0, sizeof(mfxExtVPPFrameRateConversion)); -vpp->frc_conf.Header.BufferId = MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION; -vpp->frc_conf.Header.BufferSz = sizeof(mfxExtVPPFrameRateConversion); -vpp->frc_conf.Algorithm = MFX_FRCALGM_DISTRIBUTED_TIMESTAMP; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->frc_conf; +INIT_MFX_EXTBUF(frc_conf, MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION); +SET_MFX_PARAM_FIELD(frc_conf, Algorithm, MFX_FRCALGM_DISTRIBUTED_TIMESTAMP); } if (vpp->denoise) { -memset(&vpp->denoise_conf, 0, sizeof(mfxExtVPPDenoise)); -vpp->denoise_conf.Header.BufferId = MFX_EXTBUFF_VPP_DENOISE; -vpp->denoise_conf.Header.BufferSz = sizeof(mfxExtVPPDenoise); -vpp->denoise_conf.DenoiseFactor = vpp->denoise; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->denoise_conf; +INIT_MFX_EXTBUF(denoise_conf, MFX_EXTBUFF_VPP_DENOISE); +SET_MFX_PARAM_FIELD(denoise_conf, DenoiseFactor, vpp->denoise); } if (vpp->detail) { -memset(&vpp->detail_conf, 0, sizeof(mfxExtVPPDetail)); -vpp->detail_conf.Header.BufferId = MFX_EXTBUFF_VPP_DETAIL; -vpp->detail_conf.Header.BufferSz = sizeof(mfxExtVPPDetail); -vpp->detail_conf.DetailFactor = vpp->detail; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->detail_conf; +INIT_MFX_EXTBUF(detail_conf, MFX_EXTBUFF_VPP_DETAIL); +SET_MFX_PARAM_FIELD(detail_conf, DetailFactor, vpp->detail); } if (vpp->procamp) { -memset(&vpp->procamp_conf, 0, sizeof(mfxExtVPPProcAmp)); -vpp->procamp_conf.Header.BufferId = MFX_EXTBUFF_VPP_PROCAMP; -vpp->procamp_conf.Header.BufferSz = sizeof(mfxExtVPPProcAmp); -vpp->procamp_conf.Hue = vpp->hue; -vpp->procamp_conf.Saturation = vpp->saturation; -vpp->procamp_conf.Contrast = vpp->contrast; -vpp->procamp_conf.Brightness = vpp->brightness; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->procamp_conf; +INIT_MFX_EXTBUF(procamp_conf, MFX_EXTBUFF_VPP_PROCAMP); +SET_MFX_PARAM_FIELD(procamp_conf, Hue, vpp->hue); +SET_MFX_PARAM_FIELD(procamp_conf, Saturation, vpp->saturation); +SET_MFX_PARAM_FIELD(procamp_conf, Contrast, vpp->contrast); +SET_MFX_PARAM_FIELD(procamp_conf, Brightness, vpp->brightness); } if (vpp->transpose >= 0) { @@ -466,18 +457,14 @@ static int config_output(AVFilterLink *outlink) if (vpp->rotate) { #ifdef QSV_HAVE_ROTATION -memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation)); -vpp->rotation_conf.Header.BufferId = MFX_EXTBUFF_VPP_ROTATION; -vpp->rotation_conf.Header.BufferSz = sizeof(mfxExtVPPRotation); -vpp->rotation_conf.Angle = vpp->rotate; +INIT_MFX_EXTBUF(rotation_conf, MFX_EXTBUFF_VPP_ROTATION); +SET_MFX_PARAM_FIELD(rotation_conf, Angle, vpp->rotate); if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp->rotate) { FFSWAP(int, vpp->out_width, vpp->out_height); FFSWAP(int, outlink->w, outlink->h); av_log(ctx, AV_LOG_DEBUG, "Swap width and height for clock/cclock
[FFmpeg-devel] [PATCH 06/22] lavf/vpp_qsv: allow special values for the output dimensions
Special values are: 0 = original width/height -1 = keep original aspect This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 47 ++-- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index adcfd0484d..7afbb3c983 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -59,6 +59,11 @@ typedef struct VPPContext{ mfxExtVPPRotation rotation_conf; mfxExtVPPMirroring mirroring_conf; +/** + * New dimensions. Special values are: + * 0 = original width/height + * -1 = keep original aspect + */ int out_width; int out_height; /** @@ -122,10 +127,10 @@ static const AVOption options[] = { { "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, 0, 0, FLAGS }, { "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, 0, 0, FLAGS }, -{ "w", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "width", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "h", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, -{ "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, +{ "w", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, +{ "width", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, +{ "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, +{ "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, @@ -267,6 +272,7 @@ static int config_input(AVFilterLink *inlink) AVFilterContext *ctx = inlink->dst; VPPContext *vpp = ctx->priv; int ret; +int64_t ow, oh; if (vpp->framerate.den == 0 || vpp->framerate.num == 0) vpp->framerate = inlink->frame_rate; @@ -280,11 +286,38 @@ static int config_input(AVFilterLink *inlink) return ret; } -if (vpp->out_height == 0 || vpp->out_width == 0) { -vpp->out_width = inlink->w; -vpp->out_height = inlink->h; +ow = vpp->out_width; +oh = vpp->out_height; + +/* sanity check params */ +if (ow < -1 || oh < -1) { +av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n"); +return AVERROR(EINVAL); } +if (ow == -1 && oh == -1) +vpp->out_width = vpp->out_height = 0; + +if (!(ow = vpp->out_width)) +ow = inlink->w; + +if (!(oh = vpp->out_height)) +oh = inlink->h; + +if (ow == -1) +ow = av_rescale(oh, inlink->w, inlink->h); + +if (oh == -1) +oh = av_rescale(ow, inlink->h, inlink->w); + +if (ow > INT_MAX || oh > INT_MAX || +(oh * inlink->w) > INT_MAX || +(ow * inlink->h) > INT_MAX) +av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); + +vpp->out_width = ow; +vpp->out_height = oh; + if (vpp->use_crop) { vpp->crop_x = FFMAX(vpp->crop_x, 0); vpp->crop_y = FFMAX(vpp->crop_y, 0); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 11/22] lavf/vpp_qsv: factor common QSV filter definition
--- libavfilter/vf_vpp_qsv.c | 195 +-- 1 file changed, 86 insertions(+), 109 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index dd3afb5e10..03785e9398 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -105,44 +105,6 @@ typedef struct VPPContext{ int scaling_mode; } VPPContext; -static const AVOption options[] = { -{ "deinterlace", "deinterlace mode: 0=off, 1=bob, 2=advanced", OFFSET(deinterlace), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MFX_DEINTERLACING_ADVANCED, .flags = FLAGS, "deinterlace" }, -{ "bob", "Bob deinterlace mode.", 0, AV_OPT_TYPE_CONST,{ .i64 = MFX_DEINTERLACING_BOB }, .flags = FLAGS, "deinterlace" }, -{ "advanced","Advanced deinterlace mode. ",0, AV_OPT_TYPE_CONST,{ .i64 = MFX_DEINTERLACING_ADVANCED }, .flags = FLAGS, "deinterlace" }, - -{ "denoise", "denoise level [0, 100]", OFFSET(denoise), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS }, -{ "detail", "enhancement level [0, 100]", OFFSET(detail), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS }, -{ "framerate", "output framerate", OFFSET(framerate), AV_OPT_TYPE_RATIONAL, { .dbl = 0.0 },0, DBL_MAX, .flags = FLAGS }, -{ "procamp", "Enable ProcAmp", OFFSET(procamp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS}, -{ "hue", "ProcAmp hue", OFFSET(hue), AV_OPT_TYPE_FLOAT,{ .dbl = 0.0 }, -180.0, 180.0, .flags = FLAGS}, -{ "saturation", "ProcAmp saturation", OFFSET(saturation), AV_OPT_TYPE_FLOAT,{ .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS}, -{ "contrast","ProcAmp contrast", OFFSET(contrast), AV_OPT_TYPE_FLOAT,{ .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS}, -{ "brightness", "ProcAmp brightness", OFFSET(brightness), AV_OPT_TYPE_FLOAT,{ .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS}, - -{ "transpose", "set transpose direction", OFFSET(transpose), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, FLAGS, "transpose"}, -{ "cclock_hflip", "rotate counter-clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" }, -{ "clock", "rotate clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK }, .flags=FLAGS, .unit = "transpose" }, -{ "cclock","rotate counter-clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK }, .flags=FLAGS, .unit = "transpose" }, -{ "clock_hflip", "rotate clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" }, -{ "reversal", "rotate by half-turn", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_REVERSAL}, .flags=FLAGS, .unit = "transpose" }, -{ "hflip", "flip horizontally", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_HFLIP }, .flags=FLAGS, .unit = "transpose" }, -{ "vflip", "flip vertically", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_VFLIP }, .flags=FLAGS, .unit = "transpose" }, - -{ "cw", "set the width crop area expression", OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, 0, 0, FLAGS }, -{ "ch", "set the height crop area expression", OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, 0, 0, FLAGS }, -{ "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, 0, 0, FLAGS }, -{ "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, 0, 0, FLAGS }, - -{ "w", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "width", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, -{ "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, -{ "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, -{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, - -{ NULL } -}; - static co
[FFmpeg-devel] [PATCH 10/22] lavf/scale_qsv: re-use VPPContext for scale_qsv filter
All features are implemented in vpp_qsv filter, scale_qsv can be taken as a special case of vpp_qsv filter now, we re-use VPPContext with a different option arrary and pixel formats --- libavfilter/Makefile | 2 +- libavfilter/vf_scale_qsv.c | 334 - libavfilter/vf_vpp_qsv.c | 55 ++ 3 files changed, 56 insertions(+), 335 deletions(-) delete mode 100644 libavfilter/vf_scale_qsv.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index bc81033e3f..9e6bb87c4c 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -396,7 +396,7 @@ OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o scale_eval.o OBJS-$(CONFIG_SCALE_CUDA_FILTER) += vf_scale_cuda.o scale_eval.o \ vf_scale_cuda.ptx.o vf_scale_cuda_bicubic.ptx.o OBJS-$(CONFIG_SCALE_NPP_FILTER) += vf_scale_npp.o scale_eval.o -OBJS-$(CONFIG_SCALE_QSV_FILTER) += vf_scale_qsv.o +OBJS-$(CONFIG_SCALE_QSV_FILTER) += vf_vpp_qsv.o OBJS-$(CONFIG_SCALE_VAAPI_FILTER)+= vf_scale_vaapi.o scale_eval.o vaapi_vpp.o OBJS-$(CONFIG_SCALE_VULKAN_FILTER) += vf_scale_vulkan.o vulkan.o OBJS-$(CONFIG_SCALE2REF_FILTER) += vf_scale.o scale_eval.o diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c deleted file mode 100644 index f8e937e40e..00 --- a/libavfilter/vf_scale_qsv.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * 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 - */ - -/** - * @file - * scale video filter - QSV - */ - -#include - -#include -#include - -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/hwcontext.h" -#include "libavutil/hwcontext_qsv.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/time.h" -#include "libavfilter/qsvvpp.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -static const char *const var_names[] = { -"in_w", "iw", -"in_h", "ih", -"out_w", "ow", -"out_h", "oh", -"a", "dar", -"sar", -NULL -}; - -enum var_name { -VAR_IN_W, VAR_IW, -VAR_IN_H, VAR_IH, -VAR_OUT_W, VAR_OW, -VAR_OUT_H, VAR_OH, -VAR_A, VAR_DAR, -VAR_SAR, -VARS_NB -}; - -#define QSV_HAVE_SCALING_CONFIG QSV_VERSION_ATLEAST(1, 19) - -typedef struct QSVScaleContext { -QSVVPPContext qsv; - -#if QSV_HAVE_SCALING_CONFIG -mfxExtVPPScaling scale_conf; -#endif -int mode; - -/** - * New dimensions. Special values are: - * 0 = original width/height - * -1 = keep original aspect - */ -int w, h; - -/** - * Output sw format. AV_PIX_FMT_NONE for no conversion. - */ -enum AVPixelFormat format; - -char *w_expr; ///< width expression string -char *h_expr; ///< height expression string -char *format_str; -} QSVScaleContext; - -static av_cold int qsvscale_init(AVFilterContext *ctx) -{ -QSVScaleContext *s = ctx->priv; - -if (!strcmp(s->format_str, "same")) { -s->format = AV_PIX_FMT_NONE; -} else { -s->format = av_get_pix_fmt(s->format_str); -if (s->format == AV_PIX_FMT_NONE) { -av_log(ctx, AV_LOG_ERROR, "Unrecognized pixel format: %s\n", s->format_str); -return AVERROR(EINVAL); -} -} - -return 0; -} - -static av_cold void qsvscale_uninit(AVFilterContext *ctx) -{ -ff_qsvvpp_close(ctx); -} - -static int qsvscale_query_formats(AVFilterContext *ctx) -{ -static const enum AVPixelFormat pixel_formats[] = { -AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, -}; -AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); -int ret; - -if ((ret = ff_set_common_formats(ctx, pix_fmts)) < 0) -return ret; - -return 0; -} - -static int qsvscale_config_props(AVFilterLink *outlink) -{ -AVFilterContext *ctx = outlink->src; -AVFilterLink *inlink = outlink->src->inputs[0]; -QSVScaleContext *s = ctx->priv; -QSVVPPParamparam = { NULL }; -#if QSV_HAVE_SCALING_CONFIG -mfxEx
[FFmpeg-devel] [PATCH 08/22] lavf/vpp_qsv: pass scaling mode to the SDK
After this patch, the scaling mode will be passed to the SDK when the scaling mode is not equal to the default mode. This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index c9a7b0ceb9..fd45c4f352 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -43,9 +43,10 @@ #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM) /* number of video enhancement filters */ -#define ENH_FILTERS_COUNT (7) +#define ENH_FILTERS_COUNT (8) #define QSV_HAVE_ROTATION QSV_VERSION_ATLEAST(1, 17) #define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19) +#define QSV_HAVE_SCALING QSV_VERSION_ATLEAST(1, 19) typedef struct VPPContext{ QSVVPPContext qsv; @@ -58,6 +59,9 @@ typedef struct VPPContext{ mfxExtVPPProcAmp procamp_conf; mfxExtVPPRotation rotation_conf; mfxExtVPPMirroring mirroring_conf; +#if QSV_HAVE_SCALING +mfxExtVPPScaling scaling_conf; +#endif /** * New dimensions. Special values are: @@ -97,6 +101,8 @@ typedef struct VPPContext{ char *cx, *cy, *cw, *ch; char *ow, *oh; char *output_format_str; + +int scaling_mode; } VPPContext; static const AVOption options[] = { @@ -483,6 +489,17 @@ static int config_output(AVFilterLink *outlink) #endif } +if (vpp->scaling_mode) { +#ifdef QSV_HAVE_SCALING +INIT_MFX_EXTBUF(scaling_conf, MFX_EXTBUFF_VPP_SCALING); +SET_MFX_PARAM_FIELD(scaling_conf, ScalingMode, vpp->scaling_mode); +#else +av_log(ctx, AV_LOG_WARNING, "The scaling_mode option is " +"not supported with this MSDK version.\n"); +vpp->scaling_mode = 0; +#endif +} + #undef INIT_MFX_EXTBUF #undef SET_MFX_PARAM_FIELD -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 20/22] lavf/deinterlace_qsv: add async_depth option
Allow user to set async depth for deinterlace_qsv --- libavfilter/vf_vpp_qsv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index c0afb001b9..bb3aebf047 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -711,6 +711,7 @@ static const AVOption qsvdeint_options[] = { { "mode", "set deinterlace mode", OFFSET(deinterlace), AV_OPT_TYPE_INT, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, { "bob", "bob algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, { "advanced", "Motion adaptive algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, +{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, { NULL }, }; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 22/22] lavf/vpp_qsv: allow user to set scaling mode for vpp_qsv filter
option 'scaling' accepts one of low_power and hq $ ffmpeg -init_hw_device qsv -hwaccel qsv -c:v h264_qsv -i input.h264 -vf "vpp_qsv=scaling=hq" -f null - --- libavfilter/vf_vpp_qsv.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 4607ece1c5..b994f1e408 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -637,6 +637,16 @@ static const AVOption vpp_options[] = { { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, +#if QSV_HAVE_SCALING +{ "scaling", "set scaling mode",OFFSET(scaling_mode), AV_OPT_TYPE_INT,{ .i64 = MFX_SCALING_MODE_DEFAULT}, MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY, FLAGS, "mode"}, +{ "low_power", "low power mode",0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX, FLAGS, "mode"}, +{ "hq","high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_QUALITY}, INT_MIN, INT_MAX, FLAGS, "mode"}, +#else +{ "scaling", "(not supported)", OFFSET(scaling_mode), AV_OPT_TYPE_INT,{ .i64 = 0}, 0, INT_MAX, FLAGS, "mode"}, +{ "low_power", "", 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, FLAGS, "mode"}, +{ "hq","", 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, FLAGS, "mode"}, +#endif + { NULL } }; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 21/22] lavf/deinterlace_qsv: add more input / output pixel formats
NV12 is added in system memory and the command below may work now. $ ffmpeg -init_hw_device qsv -c:v h264_qsv -i input.h264 -vf deinterlace_qsv -f null - --- libavfilter/vf_vpp_qsv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index bb3aebf047..4607ece1c5 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -718,7 +718,9 @@ static const AVOption qsvdeint_options[] = { static int qsvdeint_query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pixel_formats[] = { -AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, +AV_PIX_FMT_NV12, +AV_PIX_FMT_QSV, +AV_PIX_FMT_NONE, }; AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 13/22] lavf/scale_qsv: add more input / output pixel formats
NV12 and P010 are added $ ffmpeg -init_hw_device qsv -c:v h264_qsv -i input.h264 -vf "scale_qsv=format=p010" -f null - --- libavfilter/vf_vpp_qsv.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index bceee8c4df..29ba220665 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -665,7 +665,10 @@ DEFINE_QSV_FILTER(vpp, vpp, "VPP"); static int qsvscale_query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pixel_formats[] = { -AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, +AV_PIX_FMT_NV12, +AV_PIX_FMT_P010, +AV_PIX_FMT_QSV, +AV_PIX_FMT_NONE, }; AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 15/22] lavf/qsvvpp: avoid overriding the returned value
Currently the returned value from MFXVideoVPP_RunFrameVPPAsync() is overridden, so the check of 'ret == MFX_ERR_MORE_SURFACE' is always false when MFX_ERR_MORE_SURFACE is returned from MFXVideoVPP_RunFrameVPPAsync() --- libavfilter/qsvvpp.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 5b0b30e23c..82a8e29387 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -787,7 +787,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr AVFilterLink *outlink = ctx->outputs[0]; mfxSyncPoint sync; QSVFrame *in_frame, *out_frame, *tmp; -int ret, filter_ret; +int ret, ret1, filter_ret; while (s->eof && qsv_fifo_size(s->async_fifo)) { av_fifo_generic_read(s->async_fifo, &tmp, sizeof(tmp), NULL); @@ -849,8 +849,13 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr av_fifo_generic_read(s->async_fifo, &sync, sizeof(sync), NULL); do { -ret = MFXVideoCORE_SyncOperation(s->session, sync, 1000); -} while (ret == MFX_WRN_IN_EXECUTION); +ret1 = MFXVideoCORE_SyncOperation(s->session, sync, 1000); +} while (ret1 == MFX_WRN_IN_EXECUTION); + +if (ret1 < 0) { +ret = ret1; +break; +} filter_ret = s->filter_frame(outlink, tmp->frame); if (filter_ret < 0) { -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 12/22] lavf/scale_qsv: add new options for scale_qsv filter
Allow user to set crop area and async depth --- libavfilter/vf_vpp_qsv.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 03785e9398..bceee8c4df 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -675,6 +675,10 @@ static int qsvscale_query_formats(AVFilterContext *ctx) static const AVOption qsvscale_options[] = { { "w", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, { "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, +{ "cw", "set the width crop area expression", OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, +{ "ch", "set the height crop area expression", OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, +{ "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(iw-ow)/2" }, .flags = FLAGS }, +{ "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(ih-oh)/2" }, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, #if QSV_HAVE_SCALING @@ -687,6 +691,8 @@ static const AVOption qsvscale_options[] = { { "hq","", 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, FLAGS, "mode"}, #endif +{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, + { NULL }, }; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 14/22] lavf/vpp_qsv: double the framerate for deinterlacing
--- libavfilter/vf_vpp_qsv.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 29ba220665..ec35f85b04 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -255,10 +255,14 @@ static int config_input(AVFilterLink *inlink) int ret; int64_t ow, oh; -if (vpp->framerate.den == 0 || vpp->framerate.num == 0) +/* Ignore user's setting for framerate when deinterlacing is used */ +if (vpp->deinterlace) +vpp->framerate = av_mul_q(inlink->frame_rate, + (AVRational){ 2, 1 }); +else if (vpp->framerate.den == 0 || vpp->framerate.num == 0) vpp->framerate = inlink->frame_rate; -if (av_cmp_q(vpp->framerate, inlink->frame_rate)) +if (!vpp->deinterlace && av_cmp_q(vpp->framerate, inlink->frame_rate)) vpp->use_frc = 1; ret = eval_expr(ctx); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 16/22] lavf/qsvvpp: set PTS for output frame
When the SDK returns MFX_ERR_MORE_SURFACE, the PTS is not set for the output frame. We assign a PTS calculated from the input frame to the output frame. After applying this patch, we may avoid the error below: [null @ 0x56395cab4ae0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 456 >= 0 Note this patch only fixes PTS issue when deinterlacing is enabled --- libavfilter/qsvvpp.c | 21 +++-- libavfilter/qsvvpp.h | 3 +++ libavfilter/vf_vpp_qsv.c | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 82a8e29387..01d9d754d3 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -653,6 +653,7 @@ int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param) int ret; QSVVPPContext *s = avctx->priv; +s->last_in_pts = AV_NOPTS_VALUE; s->filter_frame = param->filter_frame; if (!s->filter_frame) s->filter_frame = ff_filter_frame; @@ -769,6 +770,8 @@ int ff_qsvvpp_close(AVFilterContext *avctx) s->session = NULL; } +s->last_in_pts = AV_NOPTS_VALUE; + /* release all the resources */ clear_frame_list(&s->in_frame_list); clear_frame_list(&s->out_frame_list); @@ -788,6 +791,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr mfxSyncPoint sync; QSVFrame *in_frame, *out_frame, *tmp; int ret, ret1, filter_ret; +int64_t dpts = 0; while (s->eof && qsv_fifo_size(s->async_fifo)) { av_fifo_generic_read(s->async_fifo, &tmp, sizeof(tmp), NULL); @@ -836,8 +840,19 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr ret = AVERROR(EAGAIN); break; } -out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp, - default_tb, outlink->time_base); + +/* TODO: calculate the PTS for other cases */ +if (s->deinterlace_enabled && +s->last_in_pts != AV_NOPTS_VALUE && +ret == MFX_ERR_MORE_SURFACE && +out_frame->surface.Data.TimeStamp == MFX_TIMESTAMP_UNKNOWN) +dpts = (in_frame->frame->pts - s->last_in_pts) / 2; +else +dpts = 0; + +out_frame->frame->pts = av_rescale_q(in_frame->frame->pts - dpts, + inlink->time_base, + outlink->time_base); out_frame->queued++; av_fifo_generic_write(s->async_fifo, &out_frame, sizeof(out_frame), NULL); @@ -870,5 +885,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr } } while(ret == MFX_ERR_MORE_SURFACE); +s->last_in_pts = in_frame->frame->pts; + return ret; } diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index b6fe0d3fa7..8627c8c868 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -74,8 +74,11 @@ typedef struct QSVVPPContext { int got_frame; int async_depth; int eof; +int deinterlace_enabled; /** order with frame_out, sync */ AVFifoBuffer *async_fifo; + +int64_t last_in_pts; } QSVVPPContext; typedef struct QSVVPPCrop { diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index ec35f85b04..018b0e8689 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -369,6 +369,8 @@ static int config_output(AVFilterLink *outlink) vpp->extbuf.field = value; \ } while (0) +vpp->qsv.deinterlace_enabled = !!vpp->deinterlace; + if (vpp->deinterlace) { INIT_MFX_EXTBUF(deinterlace_conf, MFX_EXTBUFF_VPP_DEINTERLACING); SET_MFX_PARAM_FIELD(deinterlace_conf, Mode, (vpp->deinterlace == 1 ? -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 17/22] lavf/vpp_qsv: check output format string against NULL pointer
This is in preparation for re-using VPPContext but with a different option array for deinterlacing_qsv filter --- libavfilter/vf_vpp_qsv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 018b0e8689..90b0b25210 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -235,7 +235,7 @@ static av_cold int vpp_init(AVFilterContext *ctx) { VPPContext *vpp = ctx->priv; -if (!strcmp(vpp->output_format_str, "same")) { +if (!vpp->output_format_str || !strcmp(vpp->output_format_str, "same")) { vpp->out_format = AV_PIX_FMT_NONE; } else { vpp->out_format = av_get_pix_fmt(vpp->output_format_str); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 18/22] lavf/deinterlace_qsv: simplify deinterlace_qsv filter
Like what we did for scale_qsv filter, we use QSVVPPContext as a base context to manage MFX session for deinterlace_qsv filter --- libavfilter/vf_deinterlace_qsv.c | 492 ++- 1 file changed, 30 insertions(+), 462 deletions(-) diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c index 3c2d87c7c8..50ff553e6a 100644 --- a/libavfilter/vf_deinterlace_qsv.c +++ b/libavfilter/vf_deinterlace_qsv.c @@ -42,34 +42,10 @@ #include "internal.h" #include "video.h" -enum { -QSVDEINT_MORE_OUTPUT = 1, -QSVDEINT_MORE_INPUT, -}; - typedef struct QSVDeintContext { -const AVClass *class; - -AVBufferRef *hw_frames_ctx; -/* a clone of the main session, used internally for deinterlacing */ -mfxSession session; - -mfxMemId *mem_ids; -intnb_mem_ids; - -mfxFrameSurface1 **surface_ptrs; -int nb_surface_ptrs; +QSVVPPContext qsv; -mfxExtOpaqueSurfaceAlloc opaque_alloc; -mfxExtVPPDeinterlacing deint_conf; -mfxExtBuffer*ext_buffers[2]; -int num_ext_buffers; - -QSVFrame *work_frames; - -int64_t last_pts; - -int eof; +mfxExtVPPDeinterlacing deint_conf; /* option for Deinterlacing algorithm to be used */ int mode; @@ -77,28 +53,7 @@ typedef struct QSVDeintContext { static av_cold void qsvdeint_uninit(AVFilterContext *ctx) { -QSVDeintContext *s = ctx->priv; -QSVFrame *cur; - -if (s->session) { -MFXClose(s->session); -s->session = NULL; -} -av_buffer_unref(&s->hw_frames_ctx); - -cur = s->work_frames; -while (cur) { -s->work_frames = cur->next; -av_frame_free(&cur->frame); -av_freep(&cur); -cur = s->work_frames; -} - -av_freep(&s->mem_ids); -s->nb_mem_ids = 0; - -av_freep(&s->surface_ptrs); -s->nb_surface_ptrs = 0; +ff_qsvvpp_close(ctx); } static int qsvdeint_query_formats(AVFilterContext *ctx) @@ -115,441 +70,54 @@ static int qsvdeint_query_formats(AVFilterContext *ctx) return 0; } -static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, - mfxFrameAllocResponse *resp) -{ -AVFilterContext *ctx = pthis; -QSVDeintContext *s = ctx->priv; - -if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || -!(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || -!(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) -return MFX_ERR_UNSUPPORTED; - -resp->mids = s->mem_ids; -resp->NumFrameActual = s->nb_mem_ids; - -return MFX_ERR_NONE; -} - -static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) -{ -return MFX_ERR_NONE; -} - -static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) -{ -return MFX_ERR_UNSUPPORTED; -} - -static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) -{ -return MFX_ERR_UNSUPPORTED; -} - -static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) -{ -*hdl = mid; -return MFX_ERR_NONE; -} - -static const mfxHandleType handle_types[] = { -MFX_HANDLE_VA_DISPLAY, -MFX_HANDLE_D3D9_DEVICE_MANAGER, -MFX_HANDLE_D3D11_DEVICE, -}; - -static int init_out_session(AVFilterContext *ctx) -{ - -QSVDeintContext *s = ctx->priv; -AVHWFramesContext*hw_frames_ctx = (AVHWFramesContext*)s->hw_frames_ctx->data; -AVQSVFramesContext *hw_frames_hwctx = hw_frames_ctx->hwctx; -AVQSVDeviceContext*device_hwctx = hw_frames_ctx->device_ctx->hwctx; - -int opaque = !!(hw_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); - -mfxHDL handle = NULL; -mfxHandleType handle_type; -mfxVersion ver; -mfxIMPL impl; -mfxVideoParam par; -mfxStatus err; -int i; - -/* extract the properties of the "master" session given to us */ -err = MFXQueryIMPL(device_hwctx->session, &impl); -if (err == MFX_ERR_NONE) -err = MFXQueryVersion(device_hwctx->session, &ver); -if (err != MFX_ERR_NONE) { -av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n"); -return AVERROR_UNKNOWN; -} - -for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) { -err = MFXVideoCORE_GetHandle(device_hwctx->session, handle_types[i], &handle); -if (err == MFX_ERR_NONE) { -handle_type = handle_types[i]; -break; -} -} - -if (err < 0) -return ff_qsvvpp_print_error(ctx, err, "Error getting the session handle"); -else if (err > 0) { -ff_qsvvpp_print_warning(ctx, err, "Warning in getting the session handle"); -return AVERROR_UNKNOWN; -} - -/* create a "slave" session with those same properties, to be used for - * actual deinterlacing */ -err = MFXInit(impl, &ver, &s->session); -if (err < 0) -return ff_qsvvpp_print_error(ctx, err, "Error initializing a session for
[FFmpeg-devel] [PATCH 19/22] lavf/deinterlace_qsv: re-use VPPContext for deinterlace_qsv filter
All features are implemented in vpp_qsv filter now, so deinterlace_qsv can be taken as a specical case of vpp_qsv filter, we re-use VPPContext with a different option array and pix formats for deinterlace_qsv filter --- libavfilter/Makefile | 2 +- libavfilter/vf_deinterlace_qsv.c | 179 --- libavfilter/vf_vpp_qsv.c | 19 3 files changed, 20 insertions(+), 180 deletions(-) delete mode 100644 libavfilter/vf_deinterlace_qsv.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 9e6bb87c4c..feaf6c71a8 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -229,7 +229,7 @@ OBJS-$(CONFIG_DECONVOLVE_FILTER) += vf_convolve.o framesync.o OBJS-$(CONFIG_DEDOT_FILTER) += vf_dedot.o OBJS-$(CONFIG_DEFLATE_FILTER)+= vf_neighbor.o OBJS-$(CONFIG_DEFLICKER_FILTER) += vf_deflicker.o -OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER)+= vf_deinterlace_qsv.o +OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER)+= vf_vpp_qsv.o OBJS-$(CONFIG_DEINTERLACE_VAAPI_FILTER) += vf_deinterlace_vaapi.o vaapi_vpp.o OBJS-$(CONFIG_DEJUDDER_FILTER) += vf_dejudder.o OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c deleted file mode 100644 index 50ff553e6a..00 --- a/libavfilter/vf_deinterlace_qsv.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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 - */ - -/** - * @file - * deinterlace video filter - QSV - */ - -#include - -#include -#include - -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/hwcontext.h" -#include "libavutil/hwcontext_qsv.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/time.h" -#include "libavfilter/qsvvpp.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct QSVDeintContext { -QSVVPPContext qsv; - -mfxExtVPPDeinterlacing deint_conf; - -/* option for Deinterlacing algorithm to be used */ -int mode; -} QSVDeintContext; - -static av_cold void qsvdeint_uninit(AVFilterContext *ctx) -{ -ff_qsvvpp_close(ctx); -} - -static int qsvdeint_query_formats(AVFilterContext *ctx) -{ -static const enum AVPixelFormat pixel_formats[] = { -AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, -}; -AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); -int ret; - -if ((ret = ff_set_common_formats(ctx, pix_fmts)) < 0) -return ret; - -return 0; -} - -static int qsvdeint_config_props(AVFilterLink *outlink) -{ -AVFilterContext *ctx = outlink->src; -AVFilterLink *inlink = ctx->inputs[0]; -QSVDeintContext *s = ctx->priv; -QSVVPPParamparam = { NULL }; -mfxExtBuffer *ext_buf[1]; -enum AVPixelFormat in_format; - -qsvdeint_uninit(ctx); - -outlink->w = inlink->w; -outlink->h = inlink->h; -outlink->frame_rate = av_mul_q(inlink->frame_rate, - (AVRational){ 2, 1 }); -outlink->time_base = av_mul_q(inlink->time_base, - (AVRational){ 1, 2 }); - -if (inlink->format == AV_PIX_FMT_QSV) { -if (!inlink->hw_frames_ctx || !inlink->hw_frames_ctx->data) -return AVERROR(EINVAL); -else -in_format = ((AVHWFramesContext*)inlink->hw_frames_ctx->data)->sw_format; -} else -in_format = inlink->format; - -param.out_sw_format = in_format; -param.ext_buf = ext_buf; - -memset(&s->deint_conf, 0, sizeof(mfxExtVPPDeinterlacing)); -s->deint_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING; -s->deint_conf.Header.BufferSz = sizeof(s->deint_conf); -s->deint_conf.Mode = s->mode; -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&s->deint_conf; - -return ff_qsvvpp_init(ctx, ¶m); -} - -static int qsvdeint_filter_frame(AVFilterLink *link, AVFrame *in) -{ -AVFilterContext *ctx = link->dst; -QSVVPPContext*qsv = ctx->priv; -int ret = 0; - -ret = ff_qsvvpp_filter_frame(q
[FFmpeg-devel] [PATCH v2 00/22] clean-up QSV filters
This patchset clean up scale_qsv and deinterlace_qsv filters, and take the two filters as the special cases of vpp_qsv, so vf_scale_qsv.c and vf_deinterlace_qsv.c can be deleted from FFmpeg. In addition, a few small features are added in this patchset. --- Update the commit logs in v2 Haihao Xiang (22): lavfi/qsv: use QSVVPPContext as base context in vf_vpp_qsv/vf_overlay_qsv lavfi/scale_qsv: simplify scale_qsv filter lavfi/scale_qsv: don't need variables for constants in FFmpeg lavfi/vpp_qsv: add "a", "dar" and "sar" variables lavfi/vpp_qsv: handle NULL pointer when evaluating an expression lavfi/vpp_qsv: allow special values for the output dimensions lavfi/vpp_qsv: factorize extra MFX configuration lavfi/vpp_qsv: pass scaling mode to the SDK lavfi/vpp_qsv: add vpp_preinit callback lavfi/scale_qsv: re-use VPPContext for scale_qsv filter lavfi/vpp_qsv: factor common QSV filter definition lavfi/scale_qsv: add new options for scale_qsv filter lavfi/scale_qsv: add more input / output pixel formats lavfi/vpp_qsv: double the framerate for deinterlacing lavfi/qsvvpp: avoid overriding the returned value lavfi/qsvvpp: set PTS for output frame lavfi/vpp_qsv: check output format string against NULL pointer lavfi/deinterlace_qsv: simplify deinterlace_qsv filter lavfi/deinterlace_qsv: re-use VPPContext for deinterlace_qsv filter lavfi/deinterlace_qsv: add async_depth option lavfi/deinterlace_qsv: add more input / output pixel formats lavfi/vpp_qsv: allow user to set scaling mode for vpp_qsv filter libavfilter/Makefile | 4 +- libavfilter/qsvvpp.c | 57 ++- libavfilter/qsvvpp.h | 11 +- libavfilter/vf_deinterlace_qsv.c | 611 --- libavfilter/vf_overlay_qsv.c | 11 +- libavfilter/vf_scale_qsv.c | 685 --- libavfilter/vf_vpp_qsv.c | 474 + 7 files changed, 353 insertions(+), 1500 deletions(-) delete mode 100644 libavfilter/vf_deinterlace_qsv.c delete mode 100644 libavfilter/vf_scale_qsv.c -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 01/22] lavfi/qsv: use QSVVPPContext as base context in vf_vpp_qsv/vf_overlay_qsv
The same members between QSVVPPContext and VPPContext are removed from VPPContext, and async_depth is moved from QSVVPPParam to QSVVPPContext so that all QSV filters using QSVVPPContext may support async depth. In addition we may use QSVVPPContext as base context in other QSV filters in the future. --- libavfilter/qsvvpp.c | 25 - libavfilter/qsvvpp.h | 8 libavfilter/vf_overlay_qsv.c | 11 +-- libavfilter/vf_vpp_qsv.c | 34 +- 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 4768f6208b..5b0b30e23c 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -647,15 +647,11 @@ static unsigned int qsv_fifo_size(const AVFifoBuffer* fifo) return av_fifo_size(fifo)/qsv_fifo_item_size(); } -int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *param) +int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param) { int i; int ret; -QSVVPPContext *s; - -s = av_mallocz(sizeof(*s)); -if (!s) -return AVERROR(ENOMEM); +QSVVPPContext *s = avctx->priv; s->filter_frame = param->filter_frame; if (!s->filter_frame) @@ -722,14 +718,13 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p s->got_frame = 0; /** keep fifo size at least 1. Even when async_depth is 0, fifo is used. */ -s->async_fifo = av_fifo_alloc((param->async_depth + 1) * qsv_fifo_item_size()); -s->async_depth = param->async_depth; +s->async_fifo = av_fifo_alloc((s->async_depth + 1) * qsv_fifo_item_size()); if (!s->async_fifo) { ret = AVERROR(ENOMEM); goto failed; } -s->vpp_param.AsyncDepth = param->async_depth; +s->vpp_param.AsyncDepth = s->async_depth; if (IS_SYSTEM_MEMORY(s->in_mem_mode)) s->vpp_param.IOPattern |= MFX_IOPATTERN_IN_SYSTEM_MEMORY; @@ -756,25 +751,22 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p } else if (ret > 0) ff_qsvvpp_print_warning(avctx, ret, "Warning When creating qsvvpp"); -*vpp = s; return 0; failed: -ff_qsvvpp_free(&s); +ff_qsvvpp_close(avctx); return ret; } -int ff_qsvvpp_free(QSVVPPContext **vpp) +int ff_qsvvpp_close(AVFilterContext *avctx) { -QSVVPPContext *s = *vpp; - -if (!s) -return 0; +QSVVPPContext *s = avctx->priv; if (s->session) { MFXVideoVPP_Close(s->session); MFXClose(s->session); +s->session = NULL; } /* release all the resources */ @@ -785,7 +777,6 @@ int ff_qsvvpp_free(QSVVPPContext **vpp) av_freep(&s->ext_buffers); av_freep(&s->frame_infos); av_fifo_free(s->async_fifo); -av_freep(vpp); return 0; } diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index e0f4c8f5bb..b6fe0d3fa7 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -48,6 +48,8 @@ typedef struct QSVFrame { } QSVFrame; typedef struct QSVVPPContext { +const AVClass *class; + mfxSession session; int (*filter_frame) (AVFilterLink *outlink, AVFrame *frame); /**< callback */ enum AVPixelFormat out_sw_format; /**< Real output format */ @@ -95,15 +97,13 @@ typedef struct QSVVPPParam { /* Crop information for each input, if needed */ int num_crop; QSVVPPCrop *crop; - - int async_depth; } QSVVPPParam; /* create and initialize the QSV session */ -int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *param); +int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param); /* release the resources (eg.surfaces) */ -int ff_qsvvpp_free(QSVVPPContext **vpp); +int ff_qsvvpp_close(AVFilterContext *avctx); /* vpp filter frame and call the cb if needed */ int ff_qsvvpp_filter_frame(QSVVPPContext *vpp, AVFilterLink *inlink, AVFrame *frame); diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c index 7a4afd77d4..0b978d6528 100644 --- a/libavfilter/vf_overlay_qsv.c +++ b/libavfilter/vf_overlay_qsv.c @@ -58,10 +58,9 @@ enum var_name { }; typedef struct QSVOverlayContext { -const AVClass *class; +QSVVPPContext qsv; FFFrameSync fs; -QSVVPPContext *qsv; QSVVPPParamqsv_param; mfxExtVPPComposite comp_conf; double var_values[VAR_VARS_NB]; @@ -231,14 +230,14 @@ static int config_overlay_input(AVFilterLink *inlink) static int process_frame(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; -QSVOverlayContext *s = fs->opaque; +QSVVPPContext*qsv = fs->opaque; AVFrame*frame = NULL; int ret = 0, i; for (i = 0; i < ctx->nb_inputs; i++) { ret = ff_framesync_get_frame(fs, i, &frame, 0); if (ret == 0) -ret = ff_qsvvpp_filter_frame(s->qsv, ctx->inputs[i], frame); +
[FFmpeg-devel] [PATCH v2 02/22] lavfi/scale_qsv: simplify scale_qsv filter
Use QSVVPPContext as a base context of QSVScaleContext, hence we may re-use functions defined for QSVVPPContext to manage MFX session for scale_qsv filter too. Because system memory is taken into account in QSVVVPPContext, we may add support for non-QSV pixel formats in the future --- libavfilter/vf_scale_qsv.c | 456 + 1 file changed, 57 insertions(+), 399 deletions(-) diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index 189223a58a..77a782aa58 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -72,35 +72,13 @@ enum var_name { #define QSV_HAVE_SCALING_CONFIG QSV_VERSION_ATLEAST(1, 19) typedef struct QSVScaleContext { -const AVClass *class; - -/* a clone of the main session, used internally for scaling */ -mfxSession session; - -mfxMemId *mem_ids_in; -int nb_mem_ids_in; - -mfxMemId *mem_ids_out; -int nb_mem_ids_out; - -mfxFrameSurface1 **surface_ptrs_in; -int nb_surface_ptrs_in; - -mfxFrameSurface1 **surface_ptrs_out; -int nb_surface_ptrs_out; - -mfxExtOpaqueSurfaceAlloc opaque_alloc; +QSVVPPContext qsv; #if QSV_HAVE_SCALING_CONFIG mfxExtVPPScaling scale_conf; #endif int mode; -mfxExtBuffer *ext_buffers[1 + QSV_HAVE_SCALING_CONFIG]; -int num_ext_buf; - -int shift_width, shift_height; - /** * New dimensions. Special values are: * 0 = original width/height @@ -137,22 +115,7 @@ static av_cold int qsvscale_init(AVFilterContext *ctx) static av_cold void qsvscale_uninit(AVFilterContext *ctx) { -QSVScaleContext *s = ctx->priv; - -if (s->session) { -MFXClose(s->session); -s->session = NULL; -} - -av_freep(&s->mem_ids_in); -av_freep(&s->mem_ids_out); -s->nb_mem_ids_in = 0; -s->nb_mem_ids_out = 0; - -av_freep(&s->surface_ptrs_in); -av_freep(&s->surface_ptrs_out); -s->nb_surface_ptrs_in = 0; -s->nb_surface_ptrs_out = 0; +ff_qsvvpp_close(ctx); } static int qsvscale_query_formats(AVFilterContext *ctx) @@ -169,313 +132,20 @@ static int qsvscale_query_formats(AVFilterContext *ctx) return 0; } -static int init_out_pool(AVFilterContext *ctx, - int out_width, int out_height) -{ -QSVScaleContext *s = ctx->priv; -AVFilterLink *outlink = ctx->outputs[0]; - -AVHWFramesContext *in_frames_ctx; -AVHWFramesContext *out_frames_ctx; -AVQSVFramesContext *in_frames_hwctx; -AVQSVFramesContext *out_frames_hwctx; -enum AVPixelFormat in_format; -enum AVPixelFormat out_format; -int i, ret; - -/* check that we have a hw context */ -if (!ctx->inputs[0]->hw_frames_ctx) { -av_log(ctx, AV_LOG_ERROR, "No hw context provided on input\n"); -return AVERROR(EINVAL); -} -in_frames_ctx = (AVHWFramesContext*)ctx->inputs[0]->hw_frames_ctx->data; -in_frames_hwctx = in_frames_ctx->hwctx; - -in_format = in_frames_ctx->sw_format; -out_format= (s->format == AV_PIX_FMT_NONE) ? in_format : s->format; - -outlink->hw_frames_ctx = av_hwframe_ctx_alloc(in_frames_ctx->device_ref); -if (!outlink->hw_frames_ctx) -return AVERROR(ENOMEM); -out_frames_ctx = (AVHWFramesContext*)outlink->hw_frames_ctx->data; -out_frames_hwctx = out_frames_ctx->hwctx; - -out_frames_ctx->format= AV_PIX_FMT_QSV; -out_frames_ctx->width = FFALIGN(out_width, 16); -out_frames_ctx->height= FFALIGN(out_height, 16); -out_frames_ctx->sw_format = out_format; -out_frames_ctx->initial_pool_size = 4; - -out_frames_hwctx->frame_type = in_frames_hwctx->frame_type; - -ret = ff_filter_init_hw_frames(ctx, outlink, 32); -if (ret < 0) -return ret; - -ret = av_hwframe_ctx_init(outlink->hw_frames_ctx); -if (ret < 0) -return ret; - -for (i = 0; i < out_frames_hwctx->nb_surfaces; i++) { -mfxFrameInfo *info = &out_frames_hwctx->surfaces[i].Info; -info->CropW = out_width; -info->CropH = out_height; -} - -return 0; -} - -static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, - mfxFrameAllocResponse *resp) -{ -AVFilterContext *ctx = pthis; -QSVScaleContext *s = ctx->priv; - -if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || -!(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || -!(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) -return MFX_ERR_UNSUPPORTED; - -if (req->Type & MFX_MEMTYPE_FROM_VPPIN) { -resp->mids = s->mem_ids_in; -resp->NumFrameActual = s->nb_mem_ids_in; -} else { -resp->mids = s->mem_ids_out; -resp->NumFrameActual = s->nb_mem_ids_out; -} - -return MFX_ERR_NONE; -} - -static mfxStatus frame_free(mfxHDL pthis, mfx
[FFmpeg-devel] [PATCH v2 03/22] lavfi/scale_qsv: don't need variables for constants in FFmpeg
PI, PHI and E are defined in FFmpeg --- libavfilter/vf_scale_qsv.c | 9 - 1 file changed, 9 deletions(-) diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index 77a782aa58..f8e937e40e 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -44,9 +44,6 @@ #include "video.h" static const char *const var_names[] = { -"PI", -"PHI", -"E", "in_w", "iw", "in_h", "ih", "out_w", "ow", @@ -57,9 +54,6 @@ static const char *const var_names[] = { }; enum var_name { -VAR_PI, -VAR_PHI, -VAR_E, VAR_IN_W, VAR_IW, VAR_IN_H, VAR_IH, VAR_OUT_W, VAR_OW, @@ -147,9 +141,6 @@ static int qsvscale_config_props(AVFilterLink *outlink) int ret; enum AVPixelFormat in_format; -var_values[VAR_PI]= M_PI; -var_values[VAR_PHI] = M_PHI; -var_values[VAR_E] = M_E; var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w; var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 04/22] lavfi/vpp_qsv: add "a", "dar" and "sar" variables
Also fix the coding style for VAR index. This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 29 +++-- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 72df8a8373..e7d2c9385a 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -141,18 +141,22 @@ static const char *const var_names[] = { "ch", "cx", "cy", +"a", "dar", +"sar", NULL }; enum var_name { -VAR_iW, VAR_IN_W, -VAR_iH, VAR_IN_H, -VAR_oW, VAR_OUT_W, VAR_W, -VAR_oH, VAR_OUT_H, VAR_H, +VAR_IW, VAR_IN_W, +VAR_IH, VAR_IN_H, +VAR_OW, VAR_OUT_W, VAR_W, +VAR_OH, VAR_OUT_H, VAR_H, CW, CH, CX, CY, +VAR_A, VAR_DAR, +VAR_SAR, VAR_VARS_NB }; @@ -184,12 +188,17 @@ static int eval_expr(AVFilterContext *ctx) PASS_EXPR(cx_expr, vpp->cx); PASS_EXPR(cy_expr, vpp->cy); -var_values[VAR_iW] = +var_values[VAR_IW] = var_values[VAR_IN_W] = ctx->inputs[0]->w; -var_values[VAR_iH] = +var_values[VAR_IH] = var_values[VAR_IN_H] = ctx->inputs[0]->h; +var_values[VAR_A] = (double)var_values[VAR_IN_W] / var_values[VAR_IN_H]; +var_values[VAR_SAR] = ctx->inputs[0]->sample_aspect_ratio.num ? +(double)ctx->inputs[0]->sample_aspect_ratio.num / ctx->inputs[0]->sample_aspect_ratio.den : 1; +var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; + /* crop params */ CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h); @@ -198,15 +207,15 @@ static int eval_expr(AVFilterContext *ctx) CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); CALC_EXPR(w_expr, -var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W], +var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], vpp->out_width); CALC_EXPR(h_expr, -var_values[VAR_OUT_H] = var_values[VAR_oH] = var_values[VAR_H], +var_values[VAR_OUT_H] = var_values[VAR_OH] = var_values[VAR_H], vpp->out_height); /* calc again in case ow is relative to oh */ CALC_EXPR(w_expr, -var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W], +var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], vpp->out_width); @@ -216,7 +225,7 @@ static int eval_expr(AVFilterContext *ctx) /* calc again in case cx is relative to cy */ CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x); -if ((vpp->crop_w != var_values[VAR_iW]) || (vpp->crop_h != var_values[VAR_iH])) +if ((vpp->crop_w != var_values[VAR_IW]) || (vpp->crop_h != var_values[VAR_IH])) vpp->use_crop = 1; release: -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 05/22] lavfi/vpp_qsv: handle NULL pointer when evaluating an expression
This is in preparation for re-using VPPContext but with a different option array for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 36 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index e7d2c9385a..adcfd0484d 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -163,14 +163,19 @@ enum var_name { static int eval_expr(AVFilterContext *ctx) { #define PASS_EXPR(e, s) {\ -ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \ -if (ret < 0) {\ -av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s);\ -goto release;\ +if (s) {\ +ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \ +if (ret < 0) { \ +av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s); \ +goto release; \ +} \ }\ } -#define CALC_EXPR(e, v, i) {\ -i = v = av_expr_eval(e, var_values, NULL); \ +#define CALC_EXPR(e, v, i, d) {\ +if (e)\ +i = v = av_expr_eval(e, var_values, NULL); \ +else\ +i = v = d;\ } VPPContext *vpp = ctx->priv; double var_values[VAR_VARS_NB] = { NAN }; @@ -200,30 +205,29 @@ static int eval_expr(AVFilterContext *ctx) var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; /* crop params */ -CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); -CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h); +CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w, var_values[VAR_IW]); +CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h, var_values[VAR_IH]); /* calc again in case cw is relative to ch */ -CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); +CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w, var_values[VAR_IW]); CALC_EXPR(w_expr, var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], -vpp->out_width); +vpp->out_width, var_values[CW]); CALC_EXPR(h_expr, var_values[VAR_OUT_H] = var_values[VAR_OH] = var_values[VAR_H], -vpp->out_height); +vpp->out_height, var_values[CH]); /* calc again in case ow is relative to oh */ CALC_EXPR(w_expr, var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], -vpp->out_width); +vpp->out_width, var_values[CW]); - -CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x); -CALC_EXPR(cy_expr, var_values[CY], vpp->crop_y); +CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x, (var_values[VAR_IW] - var_values[VAR_OW]) / 2); +CALC_EXPR(cy_expr, var_values[CY], vpp->crop_y, (var_values[VAR_IH] - var_values[VAR_OH]) / 2); /* calc again in case cx is relative to cy */ -CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x); +CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x, (var_values[VAR_IW] - var_values[VAR_OW]) / 2); if ((vpp->crop_w != var_values[VAR_IW]) || (vpp->crop_h != var_values[VAR_IH])) vpp->use_crop = 1; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 08/22] lavfi/vpp_qsv: pass scaling mode to the SDK
After this patch, the scaling mode will be passed to the SDK when the scaling mode is not equal to the default mode. This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index c9a7b0ceb9..fd45c4f352 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -43,9 +43,10 @@ #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM) /* number of video enhancement filters */ -#define ENH_FILTERS_COUNT (7) +#define ENH_FILTERS_COUNT (8) #define QSV_HAVE_ROTATION QSV_VERSION_ATLEAST(1, 17) #define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19) +#define QSV_HAVE_SCALING QSV_VERSION_ATLEAST(1, 19) typedef struct VPPContext{ QSVVPPContext qsv; @@ -58,6 +59,9 @@ typedef struct VPPContext{ mfxExtVPPProcAmp procamp_conf; mfxExtVPPRotation rotation_conf; mfxExtVPPMirroring mirroring_conf; +#if QSV_HAVE_SCALING +mfxExtVPPScaling scaling_conf; +#endif /** * New dimensions. Special values are: @@ -97,6 +101,8 @@ typedef struct VPPContext{ char *cx, *cy, *cw, *ch; char *ow, *oh; char *output_format_str; + +int scaling_mode; } VPPContext; static const AVOption options[] = { @@ -483,6 +489,17 @@ static int config_output(AVFilterLink *outlink) #endif } +if (vpp->scaling_mode) { +#ifdef QSV_HAVE_SCALING +INIT_MFX_EXTBUF(scaling_conf, MFX_EXTBUFF_VPP_SCALING); +SET_MFX_PARAM_FIELD(scaling_conf, ScalingMode, vpp->scaling_mode); +#else +av_log(ctx, AV_LOG_WARNING, "The scaling_mode option is " +"not supported with this MSDK version.\n"); +vpp->scaling_mode = 0; +#endif +} + #undef INIT_MFX_EXTBUF #undef SET_MFX_PARAM_FIELD -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 09/22] lavfi/vpp_qsv: add vpp_preinit callback
Set the expected default value for options in this callback, hence we have the right values even if these options are not included in the option arrray. This is in preparation for re-using VPPContext but with a different option array for other QSV filters --- libavfilter/vf_vpp_qsv.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index fd45c4f352..fb950001c0 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -256,6 +256,19 @@ release: return ret; } +static av_cold int vpp_preinit(AVFilterContext *ctx) +{ +VPPContext *vpp = ctx->priv; +/* For AV_OPT_TYPE_STRING options, NULL is handled in other way so + * we needn't set default value here + */ +vpp->saturation = 1.0; +vpp->contrast = 1.0; +vpp->transpose = -1; + +return 0; +} + static av_cold int vpp_init(AVFilterContext *ctx) { VPPContext *vpp = ctx->priv; @@ -637,6 +650,7 @@ const AVFilter ff_vf_vpp_qsv = { .description = NULL_IF_CONFIG_SMALL("Quick Sync Video VPP."), .priv_size = sizeof(VPPContext), .query_formats = query_formats, +.preinit = vpp_preinit, .init = vpp_init, .uninit= vpp_uninit, .inputs= vpp_inputs, -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 10/22] lavfi/scale_qsv: re-use VPPContext for scale_qsv filter
All features are implemented in vpp_qsv filter, scale_qsv can be taken as a special case of vpp_qsv filter now, we re-use VPPContext with a different option arrary and pixel formats --- libavfilter/Makefile | 2 +- libavfilter/vf_scale_qsv.c | 334 - libavfilter/vf_vpp_qsv.c | 55 ++ 3 files changed, 56 insertions(+), 335 deletions(-) delete mode 100644 libavfilter/vf_scale_qsv.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index bc81033e3f..9e6bb87c4c 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -396,7 +396,7 @@ OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o scale_eval.o OBJS-$(CONFIG_SCALE_CUDA_FILTER) += vf_scale_cuda.o scale_eval.o \ vf_scale_cuda.ptx.o vf_scale_cuda_bicubic.ptx.o OBJS-$(CONFIG_SCALE_NPP_FILTER) += vf_scale_npp.o scale_eval.o -OBJS-$(CONFIG_SCALE_QSV_FILTER) += vf_scale_qsv.o +OBJS-$(CONFIG_SCALE_QSV_FILTER) += vf_vpp_qsv.o OBJS-$(CONFIG_SCALE_VAAPI_FILTER)+= vf_scale_vaapi.o scale_eval.o vaapi_vpp.o OBJS-$(CONFIG_SCALE_VULKAN_FILTER) += vf_scale_vulkan.o vulkan.o OBJS-$(CONFIG_SCALE2REF_FILTER) += vf_scale.o scale_eval.o diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c deleted file mode 100644 index f8e937e40e..00 --- a/libavfilter/vf_scale_qsv.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * 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 - */ - -/** - * @file - * scale video filter - QSV - */ - -#include - -#include -#include - -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/hwcontext.h" -#include "libavutil/hwcontext_qsv.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/time.h" -#include "libavfilter/qsvvpp.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -static const char *const var_names[] = { -"in_w", "iw", -"in_h", "ih", -"out_w", "ow", -"out_h", "oh", -"a", "dar", -"sar", -NULL -}; - -enum var_name { -VAR_IN_W, VAR_IW, -VAR_IN_H, VAR_IH, -VAR_OUT_W, VAR_OW, -VAR_OUT_H, VAR_OH, -VAR_A, VAR_DAR, -VAR_SAR, -VARS_NB -}; - -#define QSV_HAVE_SCALING_CONFIG QSV_VERSION_ATLEAST(1, 19) - -typedef struct QSVScaleContext { -QSVVPPContext qsv; - -#if QSV_HAVE_SCALING_CONFIG -mfxExtVPPScaling scale_conf; -#endif -int mode; - -/** - * New dimensions. Special values are: - * 0 = original width/height - * -1 = keep original aspect - */ -int w, h; - -/** - * Output sw format. AV_PIX_FMT_NONE for no conversion. - */ -enum AVPixelFormat format; - -char *w_expr; ///< width expression string -char *h_expr; ///< height expression string -char *format_str; -} QSVScaleContext; - -static av_cold int qsvscale_init(AVFilterContext *ctx) -{ -QSVScaleContext *s = ctx->priv; - -if (!strcmp(s->format_str, "same")) { -s->format = AV_PIX_FMT_NONE; -} else { -s->format = av_get_pix_fmt(s->format_str); -if (s->format == AV_PIX_FMT_NONE) { -av_log(ctx, AV_LOG_ERROR, "Unrecognized pixel format: %s\n", s->format_str); -return AVERROR(EINVAL); -} -} - -return 0; -} - -static av_cold void qsvscale_uninit(AVFilterContext *ctx) -{ -ff_qsvvpp_close(ctx); -} - -static int qsvscale_query_formats(AVFilterContext *ctx) -{ -static const enum AVPixelFormat pixel_formats[] = { -AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, -}; -AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); -int ret; - -if ((ret = ff_set_common_formats(ctx, pix_fmts)) < 0) -return ret; - -return 0; -} - -static int qsvscale_config_props(AVFilterLink *outlink) -{ -AVFilterContext *ctx = outlink->src; -AVFilterLink *inlink = outlink->src->inputs[0]; -QSVScaleContext *s = ctx->priv; -QSVVPPParamparam = { NULL }; -#if QSV_HAVE_SCALING_CONFIG -mfxEx
[FFmpeg-devel] [PATCH v2 06/22] lavfi/vpp_qsv: allow special values for the output dimensions
Special values are: 0 = original width/height -1 = keep original aspect This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 47 ++-- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index adcfd0484d..7afbb3c983 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -59,6 +59,11 @@ typedef struct VPPContext{ mfxExtVPPRotation rotation_conf; mfxExtVPPMirroring mirroring_conf; +/** + * New dimensions. Special values are: + * 0 = original width/height + * -1 = keep original aspect + */ int out_width; int out_height; /** @@ -122,10 +127,10 @@ static const AVOption options[] = { { "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, 0, 0, FLAGS }, { "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, 0, 0, FLAGS }, -{ "w", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "width", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "h", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, -{ "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, +{ "w", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, +{ "width", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, +{ "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, +{ "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, @@ -267,6 +272,7 @@ static int config_input(AVFilterLink *inlink) AVFilterContext *ctx = inlink->dst; VPPContext *vpp = ctx->priv; int ret; +int64_t ow, oh; if (vpp->framerate.den == 0 || vpp->framerate.num == 0) vpp->framerate = inlink->frame_rate; @@ -280,11 +286,38 @@ static int config_input(AVFilterLink *inlink) return ret; } -if (vpp->out_height == 0 || vpp->out_width == 0) { -vpp->out_width = inlink->w; -vpp->out_height = inlink->h; +ow = vpp->out_width; +oh = vpp->out_height; + +/* sanity check params */ +if (ow < -1 || oh < -1) { +av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n"); +return AVERROR(EINVAL); } +if (ow == -1 && oh == -1) +vpp->out_width = vpp->out_height = 0; + +if (!(ow = vpp->out_width)) +ow = inlink->w; + +if (!(oh = vpp->out_height)) +oh = inlink->h; + +if (ow == -1) +ow = av_rescale(oh, inlink->w, inlink->h); + +if (oh == -1) +oh = av_rescale(ow, inlink->h, inlink->w); + +if (ow > INT_MAX || oh > INT_MAX || +(oh * inlink->w) > INT_MAX || +(ow * inlink->h) > INT_MAX) +av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); + +vpp->out_width = ow; +vpp->out_height = oh; + if (vpp->use_crop) { vpp->crop_x = FFMAX(vpp->crop_x, 0); vpp->crop_y = FFMAX(vpp->crop_y, 0); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 07/22] lavfi/vpp_qsv: factorize extra MFX configuration
This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 78 +--- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 7afbb3c983..c9a7b0ceb9 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -373,53 +373,44 @@ static int config_output(AVFilterLink *outlink) param.crop = &crop; } -if (vpp->deinterlace) { -memset(&vpp->deinterlace_conf, 0, sizeof(mfxExtVPPDeinterlacing)); -vpp->deinterlace_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING; -vpp->deinterlace_conf.Header.BufferSz = sizeof(mfxExtVPPDeinterlacing); -vpp->deinterlace_conf.Mode = vpp->deinterlace == 1 ? - MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED; +#define INIT_MFX_EXTBUF(extbuf, id) do { \ +memset(&vpp->extbuf, 0, sizeof(vpp->extbuf)); \ +vpp->extbuf.Header.BufferId = id; \ +vpp->extbuf.Header.BufferSz = sizeof(vpp->extbuf); \ +param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->extbuf; \ +} while (0) + +#define SET_MFX_PARAM_FIELD(extbuf, field, value) do { \ +vpp->extbuf.field = value; \ +} while (0) -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->deinterlace_conf; +if (vpp->deinterlace) { +INIT_MFX_EXTBUF(deinterlace_conf, MFX_EXTBUFF_VPP_DEINTERLACING); +SET_MFX_PARAM_FIELD(deinterlace_conf, Mode, (vpp->deinterlace == 1 ? +MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED)); } if (vpp->use_frc) { -memset(&vpp->frc_conf, 0, sizeof(mfxExtVPPFrameRateConversion)); -vpp->frc_conf.Header.BufferId = MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION; -vpp->frc_conf.Header.BufferSz = sizeof(mfxExtVPPFrameRateConversion); -vpp->frc_conf.Algorithm = MFX_FRCALGM_DISTRIBUTED_TIMESTAMP; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->frc_conf; +INIT_MFX_EXTBUF(frc_conf, MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION); +SET_MFX_PARAM_FIELD(frc_conf, Algorithm, MFX_FRCALGM_DISTRIBUTED_TIMESTAMP); } if (vpp->denoise) { -memset(&vpp->denoise_conf, 0, sizeof(mfxExtVPPDenoise)); -vpp->denoise_conf.Header.BufferId = MFX_EXTBUFF_VPP_DENOISE; -vpp->denoise_conf.Header.BufferSz = sizeof(mfxExtVPPDenoise); -vpp->denoise_conf.DenoiseFactor = vpp->denoise; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->denoise_conf; +INIT_MFX_EXTBUF(denoise_conf, MFX_EXTBUFF_VPP_DENOISE); +SET_MFX_PARAM_FIELD(denoise_conf, DenoiseFactor, vpp->denoise); } if (vpp->detail) { -memset(&vpp->detail_conf, 0, sizeof(mfxExtVPPDetail)); -vpp->detail_conf.Header.BufferId = MFX_EXTBUFF_VPP_DETAIL; -vpp->detail_conf.Header.BufferSz = sizeof(mfxExtVPPDetail); -vpp->detail_conf.DetailFactor = vpp->detail; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->detail_conf; +INIT_MFX_EXTBUF(detail_conf, MFX_EXTBUFF_VPP_DETAIL); +SET_MFX_PARAM_FIELD(detail_conf, DetailFactor, vpp->detail); } if (vpp->procamp) { -memset(&vpp->procamp_conf, 0, sizeof(mfxExtVPPProcAmp)); -vpp->procamp_conf.Header.BufferId = MFX_EXTBUFF_VPP_PROCAMP; -vpp->procamp_conf.Header.BufferSz = sizeof(mfxExtVPPProcAmp); -vpp->procamp_conf.Hue = vpp->hue; -vpp->procamp_conf.Saturation = vpp->saturation; -vpp->procamp_conf.Contrast = vpp->contrast; -vpp->procamp_conf.Brightness = vpp->brightness; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->procamp_conf; +INIT_MFX_EXTBUF(procamp_conf, MFX_EXTBUFF_VPP_PROCAMP); +SET_MFX_PARAM_FIELD(procamp_conf, Hue, vpp->hue); +SET_MFX_PARAM_FIELD(procamp_conf, Saturation, vpp->saturation); +SET_MFX_PARAM_FIELD(procamp_conf, Contrast, vpp->contrast); +SET_MFX_PARAM_FIELD(procamp_conf, Brightness, vpp->brightness); } if (vpp->transpose >= 0) { @@ -466,18 +457,14 @@ static int config_output(AVFilterLink *outlink) if (vpp->rotate) { #ifdef QSV_HAVE_ROTATION -memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation)); -vpp->rotation_conf.Header.BufferId = MFX_EXTBUFF_VPP_ROTATION; -vpp->rotation_conf.Header.BufferSz = sizeof(mfxExtVPPRotation); -vpp->rotation_conf.Angle = vpp->rotate; +INIT_MFX_EXTBUF(rotation_conf, MFX_EXTBUFF_VPP_ROTATION); +SET_MFX_PARAM_FIELD(rotation_conf, Angle, vpp->rotate); if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp->rotate) { FFSWAP(int, vpp->out_width, vpp->out_height); FFSWAP(int, outlink->w, outlink->h); av_log(ctx, AV_LOG_DEBUG, "Swap width and height for clock/cclock
[FFmpeg-devel] [PATCH v2 11/22] lavfi/vpp_qsv: factor common QSV filter definition
--- libavfilter/vf_vpp_qsv.c | 195 +-- 1 file changed, 86 insertions(+), 109 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index dd3afb5e10..03785e9398 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -105,44 +105,6 @@ typedef struct VPPContext{ int scaling_mode; } VPPContext; -static const AVOption options[] = { -{ "deinterlace", "deinterlace mode: 0=off, 1=bob, 2=advanced", OFFSET(deinterlace), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MFX_DEINTERLACING_ADVANCED, .flags = FLAGS, "deinterlace" }, -{ "bob", "Bob deinterlace mode.", 0, AV_OPT_TYPE_CONST,{ .i64 = MFX_DEINTERLACING_BOB }, .flags = FLAGS, "deinterlace" }, -{ "advanced","Advanced deinterlace mode. ",0, AV_OPT_TYPE_CONST,{ .i64 = MFX_DEINTERLACING_ADVANCED }, .flags = FLAGS, "deinterlace" }, - -{ "denoise", "denoise level [0, 100]", OFFSET(denoise), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS }, -{ "detail", "enhancement level [0, 100]", OFFSET(detail), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS }, -{ "framerate", "output framerate", OFFSET(framerate), AV_OPT_TYPE_RATIONAL, { .dbl = 0.0 },0, DBL_MAX, .flags = FLAGS }, -{ "procamp", "Enable ProcAmp", OFFSET(procamp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS}, -{ "hue", "ProcAmp hue", OFFSET(hue), AV_OPT_TYPE_FLOAT,{ .dbl = 0.0 }, -180.0, 180.0, .flags = FLAGS}, -{ "saturation", "ProcAmp saturation", OFFSET(saturation), AV_OPT_TYPE_FLOAT,{ .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS}, -{ "contrast","ProcAmp contrast", OFFSET(contrast), AV_OPT_TYPE_FLOAT,{ .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS}, -{ "brightness", "ProcAmp brightness", OFFSET(brightness), AV_OPT_TYPE_FLOAT,{ .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS}, - -{ "transpose", "set transpose direction", OFFSET(transpose), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, FLAGS, "transpose"}, -{ "cclock_hflip", "rotate counter-clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" }, -{ "clock", "rotate clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK }, .flags=FLAGS, .unit = "transpose" }, -{ "cclock","rotate counter-clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK }, .flags=FLAGS, .unit = "transpose" }, -{ "clock_hflip", "rotate clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" }, -{ "reversal", "rotate by half-turn", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_REVERSAL}, .flags=FLAGS, .unit = "transpose" }, -{ "hflip", "flip horizontally", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_HFLIP }, .flags=FLAGS, .unit = "transpose" }, -{ "vflip", "flip vertically", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_VFLIP }, .flags=FLAGS, .unit = "transpose" }, - -{ "cw", "set the width crop area expression", OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, 0, 0, FLAGS }, -{ "ch", "set the height crop area expression", OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, 0, 0, FLAGS }, -{ "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, 0, 0, FLAGS }, -{ "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, 0, 0, FLAGS }, - -{ "w", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "width", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, -{ "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, -{ "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, -{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, - -{ NULL } -}; - static co
[FFmpeg-devel] [PATCH v2 12/22] lavfi/scale_qsv: add new options for scale_qsv filter
Allow user to set crop area and async depth --- libavfilter/vf_vpp_qsv.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 03785e9398..bceee8c4df 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -675,6 +675,10 @@ static int qsvscale_query_formats(AVFilterContext *ctx) static const AVOption qsvscale_options[] = { { "w", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, { "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, +{ "cw", "set the width crop area expression", OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, +{ "ch", "set the height crop area expression", OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, +{ "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(iw-ow)/2" }, .flags = FLAGS }, +{ "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(ih-oh)/2" }, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, #if QSV_HAVE_SCALING @@ -687,6 +691,8 @@ static const AVOption qsvscale_options[] = { { "hq","", 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, FLAGS, "mode"}, #endif +{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, + { NULL }, }; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 13/22] lavfi/scale_qsv: add more input / output pixel formats
NV12 and P010 are added $ ffmpeg -init_hw_device qsv -c:v h264_qsv -i input.h264 -vf "scale_qsv=format=p010" -f null - --- libavfilter/vf_vpp_qsv.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index bceee8c4df..29ba220665 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -665,7 +665,10 @@ DEFINE_QSV_FILTER(vpp, vpp, "VPP"); static int qsvscale_query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pixel_formats[] = { -AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, +AV_PIX_FMT_NV12, +AV_PIX_FMT_P010, +AV_PIX_FMT_QSV, +AV_PIX_FMT_NONE, }; AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 15/22] lavfi/qsvvpp: avoid overriding the returned value
Currently the returned value from MFXVideoVPP_RunFrameVPPAsync() is overridden, so the check of 'ret == MFX_ERR_MORE_SURFACE' is always false when MFX_ERR_MORE_SURFACE is returned from MFXVideoVPP_RunFrameVPPAsync() --- libavfilter/qsvvpp.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 5b0b30e23c..82a8e29387 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -787,7 +787,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr AVFilterLink *outlink = ctx->outputs[0]; mfxSyncPoint sync; QSVFrame *in_frame, *out_frame, *tmp; -int ret, filter_ret; +int ret, ret1, filter_ret; while (s->eof && qsv_fifo_size(s->async_fifo)) { av_fifo_generic_read(s->async_fifo, &tmp, sizeof(tmp), NULL); @@ -849,8 +849,13 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr av_fifo_generic_read(s->async_fifo, &sync, sizeof(sync), NULL); do { -ret = MFXVideoCORE_SyncOperation(s->session, sync, 1000); -} while (ret == MFX_WRN_IN_EXECUTION); +ret1 = MFXVideoCORE_SyncOperation(s->session, sync, 1000); +} while (ret1 == MFX_WRN_IN_EXECUTION); + +if (ret1 < 0) { +ret = ret1; +break; +} filter_ret = s->filter_frame(outlink, tmp->frame); if (filter_ret < 0) { -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 14/22] lavfi/vpp_qsv: double the framerate for deinterlacing
--- libavfilter/vf_vpp_qsv.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 29ba220665..ec35f85b04 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -255,10 +255,14 @@ static int config_input(AVFilterLink *inlink) int ret; int64_t ow, oh; -if (vpp->framerate.den == 0 || vpp->framerate.num == 0) +/* Ignore user's setting for framerate when deinterlacing is used */ +if (vpp->deinterlace) +vpp->framerate = av_mul_q(inlink->frame_rate, + (AVRational){ 2, 1 }); +else if (vpp->framerate.den == 0 || vpp->framerate.num == 0) vpp->framerate = inlink->frame_rate; -if (av_cmp_q(vpp->framerate, inlink->frame_rate)) +if (!vpp->deinterlace && av_cmp_q(vpp->framerate, inlink->frame_rate)) vpp->use_frc = 1; ret = eval_expr(ctx); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 16/22] lavfi/qsvvpp: set PTS for output frame
When the SDK returns MFX_ERR_MORE_SURFACE, the PTS is not set for the output frame. We assign a PTS calculated from the input frame to the output frame. After applying this patch, we may avoid the error below: [null @ 0x56395cab4ae0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 456 >= 0 Note this patch only fixes PTS issue when deinterlacing is enabled --- libavfilter/qsvvpp.c | 21 +++-- libavfilter/qsvvpp.h | 3 +++ libavfilter/vf_vpp_qsv.c | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 82a8e29387..01d9d754d3 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -653,6 +653,7 @@ int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param) int ret; QSVVPPContext *s = avctx->priv; +s->last_in_pts = AV_NOPTS_VALUE; s->filter_frame = param->filter_frame; if (!s->filter_frame) s->filter_frame = ff_filter_frame; @@ -769,6 +770,8 @@ int ff_qsvvpp_close(AVFilterContext *avctx) s->session = NULL; } +s->last_in_pts = AV_NOPTS_VALUE; + /* release all the resources */ clear_frame_list(&s->in_frame_list); clear_frame_list(&s->out_frame_list); @@ -788,6 +791,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr mfxSyncPoint sync; QSVFrame *in_frame, *out_frame, *tmp; int ret, ret1, filter_ret; +int64_t dpts = 0; while (s->eof && qsv_fifo_size(s->async_fifo)) { av_fifo_generic_read(s->async_fifo, &tmp, sizeof(tmp), NULL); @@ -836,8 +840,19 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr ret = AVERROR(EAGAIN); break; } -out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp, - default_tb, outlink->time_base); + +/* TODO: calculate the PTS for other cases */ +if (s->deinterlace_enabled && +s->last_in_pts != AV_NOPTS_VALUE && +ret == MFX_ERR_MORE_SURFACE && +out_frame->surface.Data.TimeStamp == MFX_TIMESTAMP_UNKNOWN) +dpts = (in_frame->frame->pts - s->last_in_pts) / 2; +else +dpts = 0; + +out_frame->frame->pts = av_rescale_q(in_frame->frame->pts - dpts, + inlink->time_base, + outlink->time_base); out_frame->queued++; av_fifo_generic_write(s->async_fifo, &out_frame, sizeof(out_frame), NULL); @@ -870,5 +885,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr } } while(ret == MFX_ERR_MORE_SURFACE); +s->last_in_pts = in_frame->frame->pts; + return ret; } diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index b6fe0d3fa7..8627c8c868 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -74,8 +74,11 @@ typedef struct QSVVPPContext { int got_frame; int async_depth; int eof; +int deinterlace_enabled; /** order with frame_out, sync */ AVFifoBuffer *async_fifo; + +int64_t last_in_pts; } QSVVPPContext; typedef struct QSVVPPCrop { diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index ec35f85b04..018b0e8689 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -369,6 +369,8 @@ static int config_output(AVFilterLink *outlink) vpp->extbuf.field = value; \ } while (0) +vpp->qsv.deinterlace_enabled = !!vpp->deinterlace; + if (vpp->deinterlace) { INIT_MFX_EXTBUF(deinterlace_conf, MFX_EXTBUFF_VPP_DEINTERLACING); SET_MFX_PARAM_FIELD(deinterlace_conf, Mode, (vpp->deinterlace == 1 ? -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 18/22] lavfi/deinterlace_qsv: simplify deinterlace_qsv filter
Like what we did for scale_qsv filter, we use QSVVPPContext as a base context to manage MFX session for deinterlace_qsv filter --- libavfilter/vf_deinterlace_qsv.c | 492 ++- 1 file changed, 30 insertions(+), 462 deletions(-) diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c index 3c2d87c7c8..50ff553e6a 100644 --- a/libavfilter/vf_deinterlace_qsv.c +++ b/libavfilter/vf_deinterlace_qsv.c @@ -42,34 +42,10 @@ #include "internal.h" #include "video.h" -enum { -QSVDEINT_MORE_OUTPUT = 1, -QSVDEINT_MORE_INPUT, -}; - typedef struct QSVDeintContext { -const AVClass *class; - -AVBufferRef *hw_frames_ctx; -/* a clone of the main session, used internally for deinterlacing */ -mfxSession session; - -mfxMemId *mem_ids; -intnb_mem_ids; - -mfxFrameSurface1 **surface_ptrs; -int nb_surface_ptrs; +QSVVPPContext qsv; -mfxExtOpaqueSurfaceAlloc opaque_alloc; -mfxExtVPPDeinterlacing deint_conf; -mfxExtBuffer*ext_buffers[2]; -int num_ext_buffers; - -QSVFrame *work_frames; - -int64_t last_pts; - -int eof; +mfxExtVPPDeinterlacing deint_conf; /* option for Deinterlacing algorithm to be used */ int mode; @@ -77,28 +53,7 @@ typedef struct QSVDeintContext { static av_cold void qsvdeint_uninit(AVFilterContext *ctx) { -QSVDeintContext *s = ctx->priv; -QSVFrame *cur; - -if (s->session) { -MFXClose(s->session); -s->session = NULL; -} -av_buffer_unref(&s->hw_frames_ctx); - -cur = s->work_frames; -while (cur) { -s->work_frames = cur->next; -av_frame_free(&cur->frame); -av_freep(&cur); -cur = s->work_frames; -} - -av_freep(&s->mem_ids); -s->nb_mem_ids = 0; - -av_freep(&s->surface_ptrs); -s->nb_surface_ptrs = 0; +ff_qsvvpp_close(ctx); } static int qsvdeint_query_formats(AVFilterContext *ctx) @@ -115,441 +70,54 @@ static int qsvdeint_query_formats(AVFilterContext *ctx) return 0; } -static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, - mfxFrameAllocResponse *resp) -{ -AVFilterContext *ctx = pthis; -QSVDeintContext *s = ctx->priv; - -if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || -!(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || -!(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) -return MFX_ERR_UNSUPPORTED; - -resp->mids = s->mem_ids; -resp->NumFrameActual = s->nb_mem_ids; - -return MFX_ERR_NONE; -} - -static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) -{ -return MFX_ERR_NONE; -} - -static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) -{ -return MFX_ERR_UNSUPPORTED; -} - -static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) -{ -return MFX_ERR_UNSUPPORTED; -} - -static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) -{ -*hdl = mid; -return MFX_ERR_NONE; -} - -static const mfxHandleType handle_types[] = { -MFX_HANDLE_VA_DISPLAY, -MFX_HANDLE_D3D9_DEVICE_MANAGER, -MFX_HANDLE_D3D11_DEVICE, -}; - -static int init_out_session(AVFilterContext *ctx) -{ - -QSVDeintContext *s = ctx->priv; -AVHWFramesContext*hw_frames_ctx = (AVHWFramesContext*)s->hw_frames_ctx->data; -AVQSVFramesContext *hw_frames_hwctx = hw_frames_ctx->hwctx; -AVQSVDeviceContext*device_hwctx = hw_frames_ctx->device_ctx->hwctx; - -int opaque = !!(hw_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); - -mfxHDL handle = NULL; -mfxHandleType handle_type; -mfxVersion ver; -mfxIMPL impl; -mfxVideoParam par; -mfxStatus err; -int i; - -/* extract the properties of the "master" session given to us */ -err = MFXQueryIMPL(device_hwctx->session, &impl); -if (err == MFX_ERR_NONE) -err = MFXQueryVersion(device_hwctx->session, &ver); -if (err != MFX_ERR_NONE) { -av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n"); -return AVERROR_UNKNOWN; -} - -for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) { -err = MFXVideoCORE_GetHandle(device_hwctx->session, handle_types[i], &handle); -if (err == MFX_ERR_NONE) { -handle_type = handle_types[i]; -break; -} -} - -if (err < 0) -return ff_qsvvpp_print_error(ctx, err, "Error getting the session handle"); -else if (err > 0) { -ff_qsvvpp_print_warning(ctx, err, "Warning in getting the session handle"); -return AVERROR_UNKNOWN; -} - -/* create a "slave" session with those same properties, to be used for - * actual deinterlacing */ -err = MFXInit(impl, &ver, &s->session); -if (err < 0) -return ff_qsvvpp_print_error(ctx, err, "Error initializing a session for
[FFmpeg-devel] [PATCH v2 17/22] lavfi/vpp_qsv: check output format string against NULL pointer
This is in preparation for re-using VPPContext but with a different option array for deinterlacing_qsv filter --- libavfilter/vf_vpp_qsv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 018b0e8689..90b0b25210 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -235,7 +235,7 @@ static av_cold int vpp_init(AVFilterContext *ctx) { VPPContext *vpp = ctx->priv; -if (!strcmp(vpp->output_format_str, "same")) { +if (!vpp->output_format_str || !strcmp(vpp->output_format_str, "same")) { vpp->out_format = AV_PIX_FMT_NONE; } else { vpp->out_format = av_get_pix_fmt(vpp->output_format_str); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 19/22] lavfi/deinterlace_qsv: re-use VPPContext for deinterlace_qsv filter
All features are implemented in vpp_qsv filter now, so deinterlace_qsv can be taken as a specical case of vpp_qsv filter, we re-use VPPContext with a different option array and pix formats for deinterlace_qsv filter --- libavfilter/Makefile | 2 +- libavfilter/vf_deinterlace_qsv.c | 179 --- libavfilter/vf_vpp_qsv.c | 19 3 files changed, 20 insertions(+), 180 deletions(-) delete mode 100644 libavfilter/vf_deinterlace_qsv.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 9e6bb87c4c..feaf6c71a8 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -229,7 +229,7 @@ OBJS-$(CONFIG_DECONVOLVE_FILTER) += vf_convolve.o framesync.o OBJS-$(CONFIG_DEDOT_FILTER) += vf_dedot.o OBJS-$(CONFIG_DEFLATE_FILTER)+= vf_neighbor.o OBJS-$(CONFIG_DEFLICKER_FILTER) += vf_deflicker.o -OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER)+= vf_deinterlace_qsv.o +OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER)+= vf_vpp_qsv.o OBJS-$(CONFIG_DEINTERLACE_VAAPI_FILTER) += vf_deinterlace_vaapi.o vaapi_vpp.o OBJS-$(CONFIG_DEJUDDER_FILTER) += vf_dejudder.o OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c deleted file mode 100644 index 50ff553e6a..00 --- a/libavfilter/vf_deinterlace_qsv.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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 - */ - -/** - * @file - * deinterlace video filter - QSV - */ - -#include - -#include -#include - -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/hwcontext.h" -#include "libavutil/hwcontext_qsv.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/time.h" -#include "libavfilter/qsvvpp.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct QSVDeintContext { -QSVVPPContext qsv; - -mfxExtVPPDeinterlacing deint_conf; - -/* option for Deinterlacing algorithm to be used */ -int mode; -} QSVDeintContext; - -static av_cold void qsvdeint_uninit(AVFilterContext *ctx) -{ -ff_qsvvpp_close(ctx); -} - -static int qsvdeint_query_formats(AVFilterContext *ctx) -{ -static const enum AVPixelFormat pixel_formats[] = { -AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, -}; -AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); -int ret; - -if ((ret = ff_set_common_formats(ctx, pix_fmts)) < 0) -return ret; - -return 0; -} - -static int qsvdeint_config_props(AVFilterLink *outlink) -{ -AVFilterContext *ctx = outlink->src; -AVFilterLink *inlink = ctx->inputs[0]; -QSVDeintContext *s = ctx->priv; -QSVVPPParamparam = { NULL }; -mfxExtBuffer *ext_buf[1]; -enum AVPixelFormat in_format; - -qsvdeint_uninit(ctx); - -outlink->w = inlink->w; -outlink->h = inlink->h; -outlink->frame_rate = av_mul_q(inlink->frame_rate, - (AVRational){ 2, 1 }); -outlink->time_base = av_mul_q(inlink->time_base, - (AVRational){ 1, 2 }); - -if (inlink->format == AV_PIX_FMT_QSV) { -if (!inlink->hw_frames_ctx || !inlink->hw_frames_ctx->data) -return AVERROR(EINVAL); -else -in_format = ((AVHWFramesContext*)inlink->hw_frames_ctx->data)->sw_format; -} else -in_format = inlink->format; - -param.out_sw_format = in_format; -param.ext_buf = ext_buf; - -memset(&s->deint_conf, 0, sizeof(mfxExtVPPDeinterlacing)); -s->deint_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING; -s->deint_conf.Header.BufferSz = sizeof(s->deint_conf); -s->deint_conf.Mode = s->mode; -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&s->deint_conf; - -return ff_qsvvpp_init(ctx, ¶m); -} - -static int qsvdeint_filter_frame(AVFilterLink *link, AVFrame *in) -{ -AVFilterContext *ctx = link->dst; -QSVVPPContext*qsv = ctx->priv; -int ret = 0; - -ret = ff_qsvvpp_filter_frame(q
[FFmpeg-devel] [PATCH v2 20/22] lavfi/deinterlace_qsv: add async_depth option
Allow user to set async depth for deinterlace_qsv --- libavfilter/vf_vpp_qsv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index c0afb001b9..bb3aebf047 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -711,6 +711,7 @@ static const AVOption qsvdeint_options[] = { { "mode", "set deinterlace mode", OFFSET(deinterlace), AV_OPT_TYPE_INT, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, { "bob", "bob algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, { "advanced", "Motion adaptive algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, +{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, { NULL }, }; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 21/22] lavfi/deinterlace_qsv: add more input / output pixel formats
NV12 is added in system memory and the command below may work now. $ ffmpeg -init_hw_device qsv -c:v h264_qsv -i input.h264 -vf deinterlace_qsv -f null - --- libavfilter/vf_vpp_qsv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index bb3aebf047..4607ece1c5 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -718,7 +718,9 @@ static const AVOption qsvdeint_options[] = { static int qsvdeint_query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pixel_formats[] = { -AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, +AV_PIX_FMT_NV12, +AV_PIX_FMT_QSV, +AV_PIX_FMT_NONE, }; AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 22/22] lavfi/vpp_qsv: allow user to set scaling mode for vpp_qsv filter
option 'scaling' accepts one of low_power and hq $ ffmpeg -init_hw_device qsv -hwaccel qsv -c:v h264_qsv -i input.h264 -vf "vpp_qsv=scaling=hq" -f null - --- libavfilter/vf_vpp_qsv.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 4607ece1c5..b994f1e408 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -637,6 +637,16 @@ static const AVOption vpp_options[] = { { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, +#if QSV_HAVE_SCALING +{ "scaling", "set scaling mode",OFFSET(scaling_mode), AV_OPT_TYPE_INT,{ .i64 = MFX_SCALING_MODE_DEFAULT}, MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY, FLAGS, "mode"}, +{ "low_power", "low power mode",0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX, FLAGS, "mode"}, +{ "hq","high quality mode", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_QUALITY}, INT_MIN, INT_MAX, FLAGS, "mode"}, +#else +{ "scaling", "(not supported)", OFFSET(scaling_mode), AV_OPT_TYPE_INT,{ .i64 = 0}, 0, INT_MAX, FLAGS, "mode"}, +{ "low_power", "", 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, FLAGS, "mode"}, +{ "hq","", 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, FLAGS, "mode"}, +#endif + { NULL } }; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] lavc/qsvdec: fix pts
The time base used for compressed bitstream and video frame in the SDK is { 1, 9 }. [1][2] This can avoid the error message below from the muxer. $> ffmpeg -hwaccel qsv -c:v hevc_qsv -i input.h265 -f null - ... [null @ 0x561c24f6f2f0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 2 >= 2 [1]https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#mfxbitstream [2]https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#mfxframedata --- libavcodec/qsvdec.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index f543defb18..622750927c 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -46,6 +46,16 @@ #include "qsv.h" #include "qsv_internal.h" +static const AVRational mfx_tb = { 1, 9 }; + +#define PTS_TO_MFX_PTS(pts, pts_tb) ((pts) == AV_NOPTS_VALUE ? \ +MFX_TIMESTAMP_UNKNOWN : pts_tb.num ? \ +av_rescale_q(pts, pts_tb, mfx_tb) : pts) + +#define MFX_PTS_TO_PTS(mfx_pts, pts_tb) ((mfx_pts) == MFX_TIMESTAMP_UNKNOWN ? \ +AV_NOPTS_VALUE : pts_tb.num ? \ +av_rescale_q(mfx_pts, mfx_tb, pts_tb) : mfx_pts) + typedef struct QSVContext { // the session used for decoding mfxSession session; @@ -308,7 +318,7 @@ static int qsv_decode_header(AVCodecContext *avctx, QSVContext *q, bs.Data = avpkt->data; bs.DataLength = avpkt->size; bs.MaxLength = bs.DataLength; -bs.TimeStamp = avpkt->pts; +bs.TimeStamp = PTS_TO_MFX_PTS(avpkt->pts, avctx->pkt_timebase); if (avctx->field_order == AV_FIELD_PROGRESSIVE) bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME; } else @@ -456,7 +466,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, bs.Data = avpkt->data; bs.DataLength = avpkt->size; bs.MaxLength = bs.DataLength; -bs.TimeStamp = avpkt->pts; +bs.TimeStamp = PTS_TO_MFX_PTS(avpkt->pts, avctx->pkt_timebase); if (avctx->field_order == AV_FIELD_PROGRESSIVE) bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME; } @@ -544,7 +554,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, outsurf = &out_frame->surface; -frame->pts = outsurf->Data.TimeStamp; +frame->pts = MFX_PTS_TO_PTS(outsurf->Data.TimeStamp, avctx->pkt_timebase); frame->repeat_pict = outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 : @@ -748,6 +758,9 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx) goto fail; } +if (!avctx->pkt_timebase.num) +av_log(avctx, AV_LOG_WARNING, "Invalid pkt_timebase, passing timestamps as-is.\n"); + return 0; fail: qsv_decode_close(avctx); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] lavfi/vf_vpp_qsv: fix the time_base for outlink
Since commit 89ffcd1, the pts on output pad is in the time base of the input link, not the time base of the output link when EOF is reached, so a filter after vpp_qsv might output some unexpected frames. In order to avoid this issue, use the same time base for input and ouput links The issue can be triggered with the command below: $> ffmpeg -hwaccel qsv -c:v hevc_qsv -i input.h265 -vf "vpp_qsv=w=1920:h=1080,fps=fps=60" -f null - [out_0_0 @ 0x55eb017b5060] 100 buffers queued in out_0_0, something may be wrong. [out_0_0 @ 0x55eb017b5060] 1000 buffers queued in out_0_0, something may be wrong. [out_0_0 @ 0x55eb017b5060] 1 buffers queued in out_0_0, something may be wrong. --- libavfilter/vf_vpp_qsv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index b9ab5c6490..74d1d51e7c 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -303,7 +303,7 @@ static int config_output(AVFilterLink *outlink) outlink->w = vpp->out_width; outlink->h = vpp->out_height; outlink->frame_rate = vpp->framerate; -outlink->time_base = av_inv_q(vpp->framerate); +outlink->time_base = inlink->time_base; param.filter_frame = NULL; param.num_ext_buf = 0; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avfilter: add QSV variants of the stack filters
Include hstack_qsv, vstack_qsv and xstack_qsv, some code is copy and pasted from other filters Example: $> ffmpeg -hwaccel qsv -c:v hevc_qsv -i input.h265 -filter_complex "[0:v][0:v]hstack_qsv" -f null - --- configure | 6 + libavfilter/Makefile | 3 + libavfilter/allfilters.c | 3 + libavfilter/vf_stack_qsv.c | 499 + 4 files changed, 511 insertions(+) create mode 100644 libavfilter/vf_stack_qsv.c diff --git a/configure b/configure index 6bfd98b384..89adb3a374 100755 --- a/configure +++ b/configure @@ -3705,6 +3705,12 @@ vpp_qsv_filter_select="qsvvpp" xfade_opencl_filter_deps="opencl" yadif_cuda_filter_deps="ffnvcodec" yadif_cuda_filter_deps_any="cuda_nvcc cuda_llvm" +hstack_qsv_filter_deps="libmfx" +hstack_qsv_filter_select="qsvvpp" +vstack_qsv_filter_deps="libmfx" +vstack_qsv_filter_select="qsvvpp" +xstack_qsv_filter_deps="libmfx" +xstack_qsv_filter_select="qsvvpp" # examples avio_list_dir_deps="avformat avutil" diff --git a/libavfilter/Makefile b/libavfilter/Makefile index bc81033e3f..16cf2c8712 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -493,6 +493,9 @@ OBJS-$(CONFIG_YAEPBLUR_FILTER) += vf_yaepblur.o OBJS-$(CONFIG_ZMQ_FILTER)+= f_zmq.o OBJS-$(CONFIG_ZOOMPAN_FILTER)+= vf_zoompan.o OBJS-$(CONFIG_ZSCALE_FILTER) += vf_zscale.o +OBJS-$(CONFIG_HSTACK_QSV_FILTER) += vf_stack_qsv.o framesync.o +OBJS-$(CONFIG_VSTACK_QSV_FILTER) += vf_stack_qsv.o framesync.o +OBJS-$(CONFIG_XSTACK_QSV_FILTER) += vf_stack_qsv.o framesync.o OBJS-$(CONFIG_ALLRGB_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_ALLYUV_FILTER) += vsrc_testsrc.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index c6afef835f..278ccb99a9 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -471,6 +471,9 @@ extern const AVFilter ff_vf_yaepblur; extern const AVFilter ff_vf_zmq; extern const AVFilter ff_vf_zoompan; extern const AVFilter ff_vf_zscale; +extern const AVFilter ff_vf_hstack_qsv; +extern const AVFilter ff_vf_vstack_qsv; +extern const AVFilter ff_vf_xstack_qsv; extern const AVFilter ff_vsrc_allrgb; extern const AVFilter ff_vsrc_allyuv; diff --git a/libavfilter/vf_stack_qsv.c b/libavfilter/vf_stack_qsv.c new file mode 100644 index 00..87f611eece --- /dev/null +++ b/libavfilter/vf_stack_qsv.c @@ -0,0 +1,499 @@ +/* + * 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 + */ + +/** + * @file + * Hardware accelerated hstack, vstack and xstack filters based on Intel Quick Sync Video VPP + */ + +#include "libavutil/opt.h" +#include "libavutil/common.h" +#include "libavutil/pixdesc.h" +#include "libavutil/eval.h" +#include "libavutil/hwcontext.h" +#include "libavutil/avstring.h" +#include "libavutil/avassert.h" +#include "libavutil/imgutils.h" +#include "libavutil/mathematics.h" +#include "libavutil/parseutils.h" + +#include "internal.h" +#include "avfilter.h" +#include "filters.h" +#include "formats.h" +#include "video.h" + +#include "framesync.h" +#include "qsvvpp.h" + +#define OFFSET(x) offsetof(QSVStackContext, x) +#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM) + +enum { +QSV_STACK_H = 0, +QSV_STACK_V = 1, +QSV_STACK_X = 2 +}; + +typedef struct QSVStackContext { +const AVClass *class; +QSVVPPContext *qsv; +QSVVPPParam qsv_param; +mfxExtVPPComposite comp_conf; +int mode; +FFFrameSync fs; + +/* Options */ +int nb_inputs; +int shortest; +double scale; +char *layout; +uint8_t fillcolor[4]; +char *fillcolor_str; +int fillcolor_enable; +} QSVStackContext; + +static void rgb2yuv(float r, float g, float b, int *y, int *u, int *v, int depth) +{ +*y = ((0.21260*219.0/255.0) * r + (0.71520*219.0/255.0) * g + + (0.07220*219.0/255.0) * b) * ((1 << depth) - 1); +*u = (-(0.11457*224.0/255.0) * r - (0.38543*224.0/255.0) * g + + (0.5*224.0/255.0) * b + 0.5) * ((1 << depth) - 1); +*v = ((0.5*224.0/255.0) * r - (0.45415*224.0/255.0) * g - + (0.04585*224.0/255.0) * b + 0.5) * ((1 << depth) - 1); +} + +static int process_frame(FFFrameSync *fs) +{ +AVF
[FFmpeg-devel] [PATCH v2 1/2] lavc/qsvdec: fix pts
The time base used for compressed bitstream and video frame in the SDK is { 1, 9 }. [1][2] This can avoid the error message below from the muxer. $> ffmpeg -hwaccel qsv -c:v hevc_qsv -i input.h265 -f null - ... [null @ 0x561c24f6f2f0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 2 >= 2 [1]https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#mfxbitstream [2]https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#mfxframedata --- libavcodec/qsvdec.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index f543defb18..622750927c 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -46,6 +46,16 @@ #include "qsv.h" #include "qsv_internal.h" +static const AVRational mfx_tb = { 1, 9 }; + +#define PTS_TO_MFX_PTS(pts, pts_tb) ((pts) == AV_NOPTS_VALUE ? \ +MFX_TIMESTAMP_UNKNOWN : pts_tb.num ? \ +av_rescale_q(pts, pts_tb, mfx_tb) : pts) + +#define MFX_PTS_TO_PTS(mfx_pts, pts_tb) ((mfx_pts) == MFX_TIMESTAMP_UNKNOWN ? \ +AV_NOPTS_VALUE : pts_tb.num ? \ +av_rescale_q(mfx_pts, mfx_tb, pts_tb) : mfx_pts) + typedef struct QSVContext { // the session used for decoding mfxSession session; @@ -308,7 +318,7 @@ static int qsv_decode_header(AVCodecContext *avctx, QSVContext *q, bs.Data = avpkt->data; bs.DataLength = avpkt->size; bs.MaxLength = bs.DataLength; -bs.TimeStamp = avpkt->pts; +bs.TimeStamp = PTS_TO_MFX_PTS(avpkt->pts, avctx->pkt_timebase); if (avctx->field_order == AV_FIELD_PROGRESSIVE) bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME; } else @@ -456,7 +466,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, bs.Data = avpkt->data; bs.DataLength = avpkt->size; bs.MaxLength = bs.DataLength; -bs.TimeStamp = avpkt->pts; +bs.TimeStamp = PTS_TO_MFX_PTS(avpkt->pts, avctx->pkt_timebase); if (avctx->field_order == AV_FIELD_PROGRESSIVE) bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME; } @@ -544,7 +554,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, outsurf = &out_frame->surface; -frame->pts = outsurf->Data.TimeStamp; +frame->pts = MFX_PTS_TO_PTS(outsurf->Data.TimeStamp, avctx->pkt_timebase); frame->repeat_pict = outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 : @@ -748,6 +758,9 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx) goto fail; } +if (!avctx->pkt_timebase.num) +av_log(avctx, AV_LOG_WARNING, "Invalid pkt_timebase, passing timestamps as-is.\n"); + return 0; fail: qsv_decode_close(avctx); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 2/2] lavfi/vf_vpp_qsv: fix the time_base for outlink
Since commit 89ffcd1, the status pts of the output link is set to a value in the input link time base, not in the output link time base when EOF is reached. Usually this pst value is larger than the required one because the output link time base is more greater than the input link time base. When "-vf vpp_qsv,fps" is used, user has to wait a long time for the ending of the pipeline because fps filter output a huge number of frames until the wrong status pts is hit. The issue can be triggered with the command below (use a clip with 1000 frames in this case): $> time ffmpeg -hwaccel qsv -c:v hevc_qsv -i input.h265 -vf "vpp_qsv=w=1920:h=1080,fps=fps=30" -f null - ... [out_0_0 @ 0x564ccd27e020] 1000 buffers queued in out_0_0, something may be wrong. frame=40119596 fps=88080 q=-0.0 Lsize=N/A time=371:28:39.96 bitrate=N/A speed=2.94e+03x video:17238889kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown real9m7.451s user2m34.102s sys 0m39.734s In order to avoid the above issue, the same time base for input and ouput links is used in this patch. Fixes ticket #9286 --- v2: update the commit log libavfilter/vf_vpp_qsv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index b9ab5c6490..74d1d51e7c 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -303,7 +303,7 @@ static int config_output(AVFilterLink *outlink) outlink->w = vpp->out_width; outlink->h = vpp->out_height; outlink->frame_rate = vpp->framerate; -outlink->time_base = av_inv_q(vpp->framerate); +outlink->time_base = inlink->time_base; param.filter_frame = NULL; param.num_ext_buf = 0; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 00/22] clean-up QSV filters
Haihao Xiang (22): lavfi/qsv: use QSVVPPContext as base context in vf_vpp_qsv/vf_overlay_qsv lavfi/scale_qsv: simplify scale_qsv filter lavfi/scale_qsv: don't need variables for constants in FFmpeg lavfi/vpp_qsv: add "a", "dar" and "sar" variables lavfi/vpp_qsv: handle NULL pointer when evaluating an expression lavfi/vpp_qsv: allow special values for the output dimensions lavfi/vpp_qsv: factorize extra MFX configuration lavfi/vpp_qsv: pass scaling mode to the SDK lavfi/vpp_qsv: add vpp_preinit callback lavfi/scale_qsv: re-use VPPContext for scale_qsv filter lavfi/vpp_qsv: factor common QSV filter definition lavfi/scale_qsv: add new options for scale_qsv filter lavfi/scale_qsv: add more input / output pixel formats lavfi/vpp_qsv: double the framerate for deinterlacing lavfi/qsvvpp: avoid overriding the returned value lavfi/qsvvpp: set PTS for output frame lavfi/vpp_qsv: check output format string against NULL pointer lavfi/deinterlace_qsv: simplify deinterlace_qsv filter lavfi/deinterlace_qsv: re-use VPPContext for deinterlace_qsv filter lavfi/deinterlace_qsv: add async_depth option lavfi/deinterlace_qsv: add more input / output pixel formats lavfi/vpp_qsv: allow user to set scaling mode for vpp_qsv filter libavfilter/Makefile | 4 +- libavfilter/qsvvpp.c | 57 ++- libavfilter/qsvvpp.h | 11 +- libavfilter/vf_deinterlace_qsv.c | 611 --- libavfilter/vf_overlay_qsv.c | 11 +- libavfilter/vf_scale_qsv.c | 685 --- libavfilter/vf_vpp_qsv.c | 476 + 7 files changed, 355 insertions(+), 1500 deletions(-) delete mode 100644 libavfilter/vf_deinterlace_qsv.c delete mode 100644 libavfilter/vf_scale_qsv.c -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 01/22] lavfi/qsv: use QSVVPPContext as base context in vf_vpp_qsv/vf_overlay_qsv
The same members between QSVVPPContext and VPPContext are removed from VPPContext, and async_depth is moved from QSVVPPParam to QSVVPPContext so that all QSV filters using QSVVPPContext may support async depth. In addition we may use QSVVPPContext as base context in other QSV filters in the future. --- libavfilter/qsvvpp.c | 25 - libavfilter/qsvvpp.h | 8 libavfilter/vf_overlay_qsv.c | 11 +-- libavfilter/vf_vpp_qsv.c | 34 +- 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 4768f6208b..5b0b30e23c 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -647,15 +647,11 @@ static unsigned int qsv_fifo_size(const AVFifoBuffer* fifo) return av_fifo_size(fifo)/qsv_fifo_item_size(); } -int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *param) +int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param) { int i; int ret; -QSVVPPContext *s; - -s = av_mallocz(sizeof(*s)); -if (!s) -return AVERROR(ENOMEM); +QSVVPPContext *s = avctx->priv; s->filter_frame = param->filter_frame; if (!s->filter_frame) @@ -722,14 +718,13 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p s->got_frame = 0; /** keep fifo size at least 1. Even when async_depth is 0, fifo is used. */ -s->async_fifo = av_fifo_alloc((param->async_depth + 1) * qsv_fifo_item_size()); -s->async_depth = param->async_depth; +s->async_fifo = av_fifo_alloc((s->async_depth + 1) * qsv_fifo_item_size()); if (!s->async_fifo) { ret = AVERROR(ENOMEM); goto failed; } -s->vpp_param.AsyncDepth = param->async_depth; +s->vpp_param.AsyncDepth = s->async_depth; if (IS_SYSTEM_MEMORY(s->in_mem_mode)) s->vpp_param.IOPattern |= MFX_IOPATTERN_IN_SYSTEM_MEMORY; @@ -756,25 +751,22 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p } else if (ret > 0) ff_qsvvpp_print_warning(avctx, ret, "Warning When creating qsvvpp"); -*vpp = s; return 0; failed: -ff_qsvvpp_free(&s); +ff_qsvvpp_close(avctx); return ret; } -int ff_qsvvpp_free(QSVVPPContext **vpp) +int ff_qsvvpp_close(AVFilterContext *avctx) { -QSVVPPContext *s = *vpp; - -if (!s) -return 0; +QSVVPPContext *s = avctx->priv; if (s->session) { MFXVideoVPP_Close(s->session); MFXClose(s->session); +s->session = NULL; } /* release all the resources */ @@ -785,7 +777,6 @@ int ff_qsvvpp_free(QSVVPPContext **vpp) av_freep(&s->ext_buffers); av_freep(&s->frame_infos); av_fifo_free(s->async_fifo); -av_freep(vpp); return 0; } diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index e0f4c8f5bb..b6fe0d3fa7 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -48,6 +48,8 @@ typedef struct QSVFrame { } QSVFrame; typedef struct QSVVPPContext { +const AVClass *class; + mfxSession session; int (*filter_frame) (AVFilterLink *outlink, AVFrame *frame); /**< callback */ enum AVPixelFormat out_sw_format; /**< Real output format */ @@ -95,15 +97,13 @@ typedef struct QSVVPPParam { /* Crop information for each input, if needed */ int num_crop; QSVVPPCrop *crop; - - int async_depth; } QSVVPPParam; /* create and initialize the QSV session */ -int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *param); +int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param); /* release the resources (eg.surfaces) */ -int ff_qsvvpp_free(QSVVPPContext **vpp); +int ff_qsvvpp_close(AVFilterContext *avctx); /* vpp filter frame and call the cb if needed */ int ff_qsvvpp_filter_frame(QSVVPPContext *vpp, AVFilterLink *inlink, AVFrame *frame); diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c index 7a4afd77d4..0b978d6528 100644 --- a/libavfilter/vf_overlay_qsv.c +++ b/libavfilter/vf_overlay_qsv.c @@ -58,10 +58,9 @@ enum var_name { }; typedef struct QSVOverlayContext { -const AVClass *class; +QSVVPPContext qsv; FFFrameSync fs; -QSVVPPContext *qsv; QSVVPPParamqsv_param; mfxExtVPPComposite comp_conf; double var_values[VAR_VARS_NB]; @@ -231,14 +230,14 @@ static int config_overlay_input(AVFilterLink *inlink) static int process_frame(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; -QSVOverlayContext *s = fs->opaque; +QSVVPPContext*qsv = fs->opaque; AVFrame*frame = NULL; int ret = 0, i; for (i = 0; i < ctx->nb_inputs; i++) { ret = ff_framesync_get_frame(fs, i, &frame, 0); if (ret == 0) -ret = ff_qsvvpp_filter_frame(s->qsv, ctx->inputs[i], frame); +
[FFmpeg-devel] [PATCH v3 02/22] lavfi/scale_qsv: simplify scale_qsv filter
Use QSVVPPContext as a base context of QSVScaleContext, hence we may re-use functions defined for QSVVPPContext to manage MFX session for scale_qsv filter too. Because system memory is taken into account in QSVVVPPContext, we may add support for non-QSV pixel formats in the future --- libavfilter/vf_scale_qsv.c | 456 + 1 file changed, 57 insertions(+), 399 deletions(-) diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index 189223a58a..77a782aa58 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -72,35 +72,13 @@ enum var_name { #define QSV_HAVE_SCALING_CONFIG QSV_VERSION_ATLEAST(1, 19) typedef struct QSVScaleContext { -const AVClass *class; - -/* a clone of the main session, used internally for scaling */ -mfxSession session; - -mfxMemId *mem_ids_in; -int nb_mem_ids_in; - -mfxMemId *mem_ids_out; -int nb_mem_ids_out; - -mfxFrameSurface1 **surface_ptrs_in; -int nb_surface_ptrs_in; - -mfxFrameSurface1 **surface_ptrs_out; -int nb_surface_ptrs_out; - -mfxExtOpaqueSurfaceAlloc opaque_alloc; +QSVVPPContext qsv; #if QSV_HAVE_SCALING_CONFIG mfxExtVPPScaling scale_conf; #endif int mode; -mfxExtBuffer *ext_buffers[1 + QSV_HAVE_SCALING_CONFIG]; -int num_ext_buf; - -int shift_width, shift_height; - /** * New dimensions. Special values are: * 0 = original width/height @@ -137,22 +115,7 @@ static av_cold int qsvscale_init(AVFilterContext *ctx) static av_cold void qsvscale_uninit(AVFilterContext *ctx) { -QSVScaleContext *s = ctx->priv; - -if (s->session) { -MFXClose(s->session); -s->session = NULL; -} - -av_freep(&s->mem_ids_in); -av_freep(&s->mem_ids_out); -s->nb_mem_ids_in = 0; -s->nb_mem_ids_out = 0; - -av_freep(&s->surface_ptrs_in); -av_freep(&s->surface_ptrs_out); -s->nb_surface_ptrs_in = 0; -s->nb_surface_ptrs_out = 0; +ff_qsvvpp_close(ctx); } static int qsvscale_query_formats(AVFilterContext *ctx) @@ -169,313 +132,20 @@ static int qsvscale_query_formats(AVFilterContext *ctx) return 0; } -static int init_out_pool(AVFilterContext *ctx, - int out_width, int out_height) -{ -QSVScaleContext *s = ctx->priv; -AVFilterLink *outlink = ctx->outputs[0]; - -AVHWFramesContext *in_frames_ctx; -AVHWFramesContext *out_frames_ctx; -AVQSVFramesContext *in_frames_hwctx; -AVQSVFramesContext *out_frames_hwctx; -enum AVPixelFormat in_format; -enum AVPixelFormat out_format; -int i, ret; - -/* check that we have a hw context */ -if (!ctx->inputs[0]->hw_frames_ctx) { -av_log(ctx, AV_LOG_ERROR, "No hw context provided on input\n"); -return AVERROR(EINVAL); -} -in_frames_ctx = (AVHWFramesContext*)ctx->inputs[0]->hw_frames_ctx->data; -in_frames_hwctx = in_frames_ctx->hwctx; - -in_format = in_frames_ctx->sw_format; -out_format= (s->format == AV_PIX_FMT_NONE) ? in_format : s->format; - -outlink->hw_frames_ctx = av_hwframe_ctx_alloc(in_frames_ctx->device_ref); -if (!outlink->hw_frames_ctx) -return AVERROR(ENOMEM); -out_frames_ctx = (AVHWFramesContext*)outlink->hw_frames_ctx->data; -out_frames_hwctx = out_frames_ctx->hwctx; - -out_frames_ctx->format= AV_PIX_FMT_QSV; -out_frames_ctx->width = FFALIGN(out_width, 16); -out_frames_ctx->height= FFALIGN(out_height, 16); -out_frames_ctx->sw_format = out_format; -out_frames_ctx->initial_pool_size = 4; - -out_frames_hwctx->frame_type = in_frames_hwctx->frame_type; - -ret = ff_filter_init_hw_frames(ctx, outlink, 32); -if (ret < 0) -return ret; - -ret = av_hwframe_ctx_init(outlink->hw_frames_ctx); -if (ret < 0) -return ret; - -for (i = 0; i < out_frames_hwctx->nb_surfaces; i++) { -mfxFrameInfo *info = &out_frames_hwctx->surfaces[i].Info; -info->CropW = out_width; -info->CropH = out_height; -} - -return 0; -} - -static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, - mfxFrameAllocResponse *resp) -{ -AVFilterContext *ctx = pthis; -QSVScaleContext *s = ctx->priv; - -if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || -!(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || -!(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) -return MFX_ERR_UNSUPPORTED; - -if (req->Type & MFX_MEMTYPE_FROM_VPPIN) { -resp->mids = s->mem_ids_in; -resp->NumFrameActual = s->nb_mem_ids_in; -} else { -resp->mids = s->mem_ids_out; -resp->NumFrameActual = s->nb_mem_ids_out; -} - -return MFX_ERR_NONE; -} - -static mfxStatus frame_free(mfxHDL pthis, mfx
[FFmpeg-devel] [PATCH v3 03/22] lavfi/scale_qsv: don't need variables for constants in FFmpeg
PI, PHI and E are defined in FFmpeg --- libavfilter/vf_scale_qsv.c | 9 - 1 file changed, 9 deletions(-) diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index 77a782aa58..f8e937e40e 100644 --- a/libavfilter/vf_scale_qsv.c +++ b/libavfilter/vf_scale_qsv.c @@ -44,9 +44,6 @@ #include "video.h" static const char *const var_names[] = { -"PI", -"PHI", -"E", "in_w", "iw", "in_h", "ih", "out_w", "ow", @@ -57,9 +54,6 @@ static const char *const var_names[] = { }; enum var_name { -VAR_PI, -VAR_PHI, -VAR_E, VAR_IN_W, VAR_IW, VAR_IN_H, VAR_IH, VAR_OUT_W, VAR_OW, @@ -147,9 +141,6 @@ static int qsvscale_config_props(AVFilterLink *outlink) int ret; enum AVPixelFormat in_format; -var_values[VAR_PI]= M_PI; -var_values[VAR_PHI] = M_PHI; -var_values[VAR_E] = M_E; var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w; var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 05/22] lavfi/vpp_qsv: handle NULL pointer when evaluating an expression
This is in preparation for re-using VPPContext but with a different option array for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 36 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index e7d2c9385a..adcfd0484d 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -163,14 +163,19 @@ enum var_name { static int eval_expr(AVFilterContext *ctx) { #define PASS_EXPR(e, s) {\ -ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \ -if (ret < 0) {\ -av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s);\ -goto release;\ +if (s) {\ +ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \ +if (ret < 0) { \ +av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s); \ +goto release; \ +} \ }\ } -#define CALC_EXPR(e, v, i) {\ -i = v = av_expr_eval(e, var_values, NULL); \ +#define CALC_EXPR(e, v, i, d) {\ +if (e)\ +i = v = av_expr_eval(e, var_values, NULL); \ +else\ +i = v = d;\ } VPPContext *vpp = ctx->priv; double var_values[VAR_VARS_NB] = { NAN }; @@ -200,30 +205,29 @@ static int eval_expr(AVFilterContext *ctx) var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; /* crop params */ -CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); -CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h); +CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w, var_values[VAR_IW]); +CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h, var_values[VAR_IH]); /* calc again in case cw is relative to ch */ -CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); +CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w, var_values[VAR_IW]); CALC_EXPR(w_expr, var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], -vpp->out_width); +vpp->out_width, var_values[CW]); CALC_EXPR(h_expr, var_values[VAR_OUT_H] = var_values[VAR_OH] = var_values[VAR_H], -vpp->out_height); +vpp->out_height, var_values[CH]); /* calc again in case ow is relative to oh */ CALC_EXPR(w_expr, var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], -vpp->out_width); +vpp->out_width, var_values[CW]); - -CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x); -CALC_EXPR(cy_expr, var_values[CY], vpp->crop_y); +CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x, (var_values[VAR_IW] - var_values[VAR_OW]) / 2); +CALC_EXPR(cy_expr, var_values[CY], vpp->crop_y, (var_values[VAR_IH] - var_values[VAR_OH]) / 2); /* calc again in case cx is relative to cy */ -CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x); +CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x, (var_values[VAR_IW] - var_values[VAR_OW]) / 2); if ((vpp->crop_w != var_values[VAR_IW]) || (vpp->crop_h != var_values[VAR_IH])) vpp->use_crop = 1; -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 06/22] lavfi/vpp_qsv: allow special values for the output dimensions
Special values are: 0 = original width/height -1 = keep original aspect This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 47 ++-- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index adcfd0484d..7afbb3c983 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -59,6 +59,11 @@ typedef struct VPPContext{ mfxExtVPPRotation rotation_conf; mfxExtVPPMirroring mirroring_conf; +/** + * New dimensions. Special values are: + * 0 = original width/height + * -1 = keep original aspect + */ int out_width; int out_height; /** @@ -122,10 +127,10 @@ static const AVOption options[] = { { "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, 0, 0, FLAGS }, { "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, 0, 0, FLAGS }, -{ "w", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "width", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "h", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, -{ "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, +{ "w", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, +{ "width", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, +{ "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, +{ "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, @@ -267,6 +272,7 @@ static int config_input(AVFilterLink *inlink) AVFilterContext *ctx = inlink->dst; VPPContext *vpp = ctx->priv; int ret; +int64_t ow, oh; if (vpp->framerate.den == 0 || vpp->framerate.num == 0) vpp->framerate = inlink->frame_rate; @@ -280,11 +286,38 @@ static int config_input(AVFilterLink *inlink) return ret; } -if (vpp->out_height == 0 || vpp->out_width == 0) { -vpp->out_width = inlink->w; -vpp->out_height = inlink->h; +ow = vpp->out_width; +oh = vpp->out_height; + +/* sanity check params */ +if (ow < -1 || oh < -1) { +av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n"); +return AVERROR(EINVAL); } +if (ow == -1 && oh == -1) +vpp->out_width = vpp->out_height = 0; + +if (!(ow = vpp->out_width)) +ow = inlink->w; + +if (!(oh = vpp->out_height)) +oh = inlink->h; + +if (ow == -1) +ow = av_rescale(oh, inlink->w, inlink->h); + +if (oh == -1) +oh = av_rescale(ow, inlink->h, inlink->w); + +if (ow > INT_MAX || oh > INT_MAX || +(oh * inlink->w) > INT_MAX || +(ow * inlink->h) > INT_MAX) +av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); + +vpp->out_width = ow; +vpp->out_height = oh; + if (vpp->use_crop) { vpp->crop_x = FFMAX(vpp->crop_x, 0); vpp->crop_y = FFMAX(vpp->crop_y, 0); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 07/22] lavfi/vpp_qsv: factorize extra MFX configuration
This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 78 +--- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 7afbb3c983..c9a7b0ceb9 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -373,53 +373,44 @@ static int config_output(AVFilterLink *outlink) param.crop = &crop; } -if (vpp->deinterlace) { -memset(&vpp->deinterlace_conf, 0, sizeof(mfxExtVPPDeinterlacing)); -vpp->deinterlace_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING; -vpp->deinterlace_conf.Header.BufferSz = sizeof(mfxExtVPPDeinterlacing); -vpp->deinterlace_conf.Mode = vpp->deinterlace == 1 ? - MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED; +#define INIT_MFX_EXTBUF(extbuf, id) do { \ +memset(&vpp->extbuf, 0, sizeof(vpp->extbuf)); \ +vpp->extbuf.Header.BufferId = id; \ +vpp->extbuf.Header.BufferSz = sizeof(vpp->extbuf); \ +param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->extbuf; \ +} while (0) + +#define SET_MFX_PARAM_FIELD(extbuf, field, value) do { \ +vpp->extbuf.field = value; \ +} while (0) -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->deinterlace_conf; +if (vpp->deinterlace) { +INIT_MFX_EXTBUF(deinterlace_conf, MFX_EXTBUFF_VPP_DEINTERLACING); +SET_MFX_PARAM_FIELD(deinterlace_conf, Mode, (vpp->deinterlace == 1 ? +MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED)); } if (vpp->use_frc) { -memset(&vpp->frc_conf, 0, sizeof(mfxExtVPPFrameRateConversion)); -vpp->frc_conf.Header.BufferId = MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION; -vpp->frc_conf.Header.BufferSz = sizeof(mfxExtVPPFrameRateConversion); -vpp->frc_conf.Algorithm = MFX_FRCALGM_DISTRIBUTED_TIMESTAMP; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->frc_conf; +INIT_MFX_EXTBUF(frc_conf, MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION); +SET_MFX_PARAM_FIELD(frc_conf, Algorithm, MFX_FRCALGM_DISTRIBUTED_TIMESTAMP); } if (vpp->denoise) { -memset(&vpp->denoise_conf, 0, sizeof(mfxExtVPPDenoise)); -vpp->denoise_conf.Header.BufferId = MFX_EXTBUFF_VPP_DENOISE; -vpp->denoise_conf.Header.BufferSz = sizeof(mfxExtVPPDenoise); -vpp->denoise_conf.DenoiseFactor = vpp->denoise; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->denoise_conf; +INIT_MFX_EXTBUF(denoise_conf, MFX_EXTBUFF_VPP_DENOISE); +SET_MFX_PARAM_FIELD(denoise_conf, DenoiseFactor, vpp->denoise); } if (vpp->detail) { -memset(&vpp->detail_conf, 0, sizeof(mfxExtVPPDetail)); -vpp->detail_conf.Header.BufferId = MFX_EXTBUFF_VPP_DETAIL; -vpp->detail_conf.Header.BufferSz = sizeof(mfxExtVPPDetail); -vpp->detail_conf.DetailFactor = vpp->detail; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->detail_conf; +INIT_MFX_EXTBUF(detail_conf, MFX_EXTBUFF_VPP_DETAIL); +SET_MFX_PARAM_FIELD(detail_conf, DetailFactor, vpp->detail); } if (vpp->procamp) { -memset(&vpp->procamp_conf, 0, sizeof(mfxExtVPPProcAmp)); -vpp->procamp_conf.Header.BufferId = MFX_EXTBUFF_VPP_PROCAMP; -vpp->procamp_conf.Header.BufferSz = sizeof(mfxExtVPPProcAmp); -vpp->procamp_conf.Hue = vpp->hue; -vpp->procamp_conf.Saturation = vpp->saturation; -vpp->procamp_conf.Contrast = vpp->contrast; -vpp->procamp_conf.Brightness = vpp->brightness; - -param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->procamp_conf; +INIT_MFX_EXTBUF(procamp_conf, MFX_EXTBUFF_VPP_PROCAMP); +SET_MFX_PARAM_FIELD(procamp_conf, Hue, vpp->hue); +SET_MFX_PARAM_FIELD(procamp_conf, Saturation, vpp->saturation); +SET_MFX_PARAM_FIELD(procamp_conf, Contrast, vpp->contrast); +SET_MFX_PARAM_FIELD(procamp_conf, Brightness, vpp->brightness); } if (vpp->transpose >= 0) { @@ -466,18 +457,14 @@ static int config_output(AVFilterLink *outlink) if (vpp->rotate) { #ifdef QSV_HAVE_ROTATION -memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation)); -vpp->rotation_conf.Header.BufferId = MFX_EXTBUFF_VPP_ROTATION; -vpp->rotation_conf.Header.BufferSz = sizeof(mfxExtVPPRotation); -vpp->rotation_conf.Angle = vpp->rotate; +INIT_MFX_EXTBUF(rotation_conf, MFX_EXTBUFF_VPP_ROTATION); +SET_MFX_PARAM_FIELD(rotation_conf, Angle, vpp->rotate); if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp->rotate) { FFSWAP(int, vpp->out_width, vpp->out_height); FFSWAP(int, outlink->w, outlink->h); av_log(ctx, AV_LOG_DEBUG, "Swap width and height for clock/cclock
[FFmpeg-devel] [PATCH v3 04/22] lavfi/vpp_qsv: add "a", "dar" and "sar" variables
Also fix the coding style for VAR index. This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 29 +++-- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 72df8a8373..e7d2c9385a 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -141,18 +141,22 @@ static const char *const var_names[] = { "ch", "cx", "cy", +"a", "dar", +"sar", NULL }; enum var_name { -VAR_iW, VAR_IN_W, -VAR_iH, VAR_IN_H, -VAR_oW, VAR_OUT_W, VAR_W, -VAR_oH, VAR_OUT_H, VAR_H, +VAR_IW, VAR_IN_W, +VAR_IH, VAR_IN_H, +VAR_OW, VAR_OUT_W, VAR_W, +VAR_OH, VAR_OUT_H, VAR_H, CW, CH, CX, CY, +VAR_A, VAR_DAR, +VAR_SAR, VAR_VARS_NB }; @@ -184,12 +188,17 @@ static int eval_expr(AVFilterContext *ctx) PASS_EXPR(cx_expr, vpp->cx); PASS_EXPR(cy_expr, vpp->cy); -var_values[VAR_iW] = +var_values[VAR_IW] = var_values[VAR_IN_W] = ctx->inputs[0]->w; -var_values[VAR_iH] = +var_values[VAR_IH] = var_values[VAR_IN_H] = ctx->inputs[0]->h; +var_values[VAR_A] = (double)var_values[VAR_IN_W] / var_values[VAR_IN_H]; +var_values[VAR_SAR] = ctx->inputs[0]->sample_aspect_ratio.num ? +(double)ctx->inputs[0]->sample_aspect_ratio.num / ctx->inputs[0]->sample_aspect_ratio.den : 1; +var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; + /* crop params */ CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h); @@ -198,15 +207,15 @@ static int eval_expr(AVFilterContext *ctx) CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w); CALC_EXPR(w_expr, -var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W], +var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], vpp->out_width); CALC_EXPR(h_expr, -var_values[VAR_OUT_H] = var_values[VAR_oH] = var_values[VAR_H], +var_values[VAR_OUT_H] = var_values[VAR_OH] = var_values[VAR_H], vpp->out_height); /* calc again in case ow is relative to oh */ CALC_EXPR(w_expr, -var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W], +var_values[VAR_OUT_W] = var_values[VAR_OW] = var_values[VAR_W], vpp->out_width); @@ -216,7 +225,7 @@ static int eval_expr(AVFilterContext *ctx) /* calc again in case cx is relative to cy */ CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x); -if ((vpp->crop_w != var_values[VAR_iW]) || (vpp->crop_h != var_values[VAR_iH])) +if ((vpp->crop_w != var_values[VAR_IW]) || (vpp->crop_h != var_values[VAR_IH])) vpp->use_crop = 1; release: -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 08/22] lavfi/vpp_qsv: pass scaling mode to the SDK
After this patch, the scaling mode will be passed to the SDK when the scaling mode is not equal to the default mode. This is in preparation for re-using VPPContext for scale_qsv filter --- libavfilter/vf_vpp_qsv.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index c9a7b0ceb9..fd45c4f352 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -43,9 +43,10 @@ #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM) /* number of video enhancement filters */ -#define ENH_FILTERS_COUNT (7) +#define ENH_FILTERS_COUNT (8) #define QSV_HAVE_ROTATION QSV_VERSION_ATLEAST(1, 17) #define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19) +#define QSV_HAVE_SCALING QSV_VERSION_ATLEAST(1, 19) typedef struct VPPContext{ QSVVPPContext qsv; @@ -58,6 +59,9 @@ typedef struct VPPContext{ mfxExtVPPProcAmp procamp_conf; mfxExtVPPRotation rotation_conf; mfxExtVPPMirroring mirroring_conf; +#if QSV_HAVE_SCALING +mfxExtVPPScaling scaling_conf; +#endif /** * New dimensions. Special values are: @@ -97,6 +101,8 @@ typedef struct VPPContext{ char *cx, *cy, *cw, *ch; char *ow, *oh; char *output_format_str; + +int scaling_mode; } VPPContext; static const AVOption options[] = { @@ -483,6 +489,17 @@ static int config_output(AVFilterLink *outlink) #endif } +if (vpp->scaling_mode) { +#ifdef QSV_HAVE_SCALING +INIT_MFX_EXTBUF(scaling_conf, MFX_EXTBUFF_VPP_SCALING); +SET_MFX_PARAM_FIELD(scaling_conf, ScalingMode, vpp->scaling_mode); +#else +av_log(ctx, AV_LOG_WARNING, "The scaling_mode option is " +"not supported with this MSDK version.\n"); +vpp->scaling_mode = 0; +#endif +} + #undef INIT_MFX_EXTBUF #undef SET_MFX_PARAM_FIELD -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 15/22] lavfi/qsvvpp: avoid overriding the returned value
Currently the returned value from MFXVideoVPP_RunFrameVPPAsync() is overridden, so the check of 'ret == MFX_ERR_MORE_SURFACE' is always false when MFX_ERR_MORE_SURFACE is returned from MFXVideoVPP_RunFrameVPPAsync() --- libavfilter/qsvvpp.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 5b0b30e23c..82a8e29387 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -787,7 +787,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr AVFilterLink *outlink = ctx->outputs[0]; mfxSyncPoint sync; QSVFrame *in_frame, *out_frame, *tmp; -int ret, filter_ret; +int ret, ret1, filter_ret; while (s->eof && qsv_fifo_size(s->async_fifo)) { av_fifo_generic_read(s->async_fifo, &tmp, sizeof(tmp), NULL); @@ -849,8 +849,13 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr av_fifo_generic_read(s->async_fifo, &sync, sizeof(sync), NULL); do { -ret = MFXVideoCORE_SyncOperation(s->session, sync, 1000); -} while (ret == MFX_WRN_IN_EXECUTION); +ret1 = MFXVideoCORE_SyncOperation(s->session, sync, 1000); +} while (ret1 == MFX_WRN_IN_EXECUTION); + +if (ret1 < 0) { +ret = ret1; +break; +} filter_ret = s->filter_frame(outlink, tmp->frame); if (filter_ret < 0) { -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 16/22] lavfi/qsvvpp: set PTS for output frame
When the SDK returns MFX_ERR_MORE_SURFACE, the PTS is not set for the output frame. We assign a PTS calculated from the input frame to the output frame. After applying this patch, we may avoid the error below: [null @ 0x56395cab4ae0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 456 >= 0 Note this patch only fixes PTS issue when deinterlacing is enabled --- libavfilter/qsvvpp.c | 21 +++-- libavfilter/qsvvpp.h | 3 +++ libavfilter/vf_vpp_qsv.c | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 82a8e29387..01d9d754d3 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -653,6 +653,7 @@ int ff_qsvvpp_init(AVFilterContext *avctx, QSVVPPParam *param) int ret; QSVVPPContext *s = avctx->priv; +s->last_in_pts = AV_NOPTS_VALUE; s->filter_frame = param->filter_frame; if (!s->filter_frame) s->filter_frame = ff_filter_frame; @@ -769,6 +770,8 @@ int ff_qsvvpp_close(AVFilterContext *avctx) s->session = NULL; } +s->last_in_pts = AV_NOPTS_VALUE; + /* release all the resources */ clear_frame_list(&s->in_frame_list); clear_frame_list(&s->out_frame_list); @@ -788,6 +791,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr mfxSyncPoint sync; QSVFrame *in_frame, *out_frame, *tmp; int ret, ret1, filter_ret; +int64_t dpts = 0; while (s->eof && qsv_fifo_size(s->async_fifo)) { av_fifo_generic_read(s->async_fifo, &tmp, sizeof(tmp), NULL); @@ -836,8 +840,19 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr ret = AVERROR(EAGAIN); break; } -out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp, - default_tb, outlink->time_base); + +/* TODO: calculate the PTS for other cases */ +if (s->deinterlace_enabled && +s->last_in_pts != AV_NOPTS_VALUE && +ret == MFX_ERR_MORE_SURFACE && +out_frame->surface.Data.TimeStamp == MFX_TIMESTAMP_UNKNOWN) +dpts = (in_frame->frame->pts - s->last_in_pts) / 2; +else +dpts = 0; + +out_frame->frame->pts = av_rescale_q(in_frame->frame->pts - dpts, + inlink->time_base, + outlink->time_base); out_frame->queued++; av_fifo_generic_write(s->async_fifo, &out_frame, sizeof(out_frame), NULL); @@ -870,5 +885,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picr } } while(ret == MFX_ERR_MORE_SURFACE); +s->last_in_pts = in_frame->frame->pts; + return ret; } diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index b6fe0d3fa7..8627c8c868 100644 --- a/libavfilter/qsvvpp.h +++ b/libavfilter/qsvvpp.h @@ -74,8 +74,11 @@ typedef struct QSVVPPContext { int got_frame; int async_depth; int eof; +int deinterlace_enabled; /** order with frame_out, sync */ AVFifoBuffer *async_fifo; + +int64_t last_in_pts; } QSVVPPContext; typedef struct QSVVPPCrop { diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index cde1acdbb0..cdf1f61b0f 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -371,6 +371,8 @@ static int config_output(AVFilterLink *outlink) vpp->extbuf.field = value; \ } while (0) +vpp->qsv.deinterlace_enabled = !!vpp->deinterlace; + if (vpp->deinterlace) { INIT_MFX_EXTBUF(deinterlace_conf, MFX_EXTBUFF_VPP_DEINTERLACING); SET_MFX_PARAM_FIELD(deinterlace_conf, Mode, (vpp->deinterlace == 1 ? -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 10/22] lavfi/scale_qsv: re-use VPPContext for scale_qsv filter
All features are implemented in vpp_qsv filter, scale_qsv can be taken as a special case of vpp_qsv filter now, we re-use VPPContext with a different option arrary and pixel formats --- libavfilter/Makefile | 2 +- libavfilter/vf_scale_qsv.c | 334 - libavfilter/vf_vpp_qsv.c | 55 ++ 3 files changed, 56 insertions(+), 335 deletions(-) delete mode 100644 libavfilter/vf_scale_qsv.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index bc81033e3f..9e6bb87c4c 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -396,7 +396,7 @@ OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o scale_eval.o OBJS-$(CONFIG_SCALE_CUDA_FILTER) += vf_scale_cuda.o scale_eval.o \ vf_scale_cuda.ptx.o vf_scale_cuda_bicubic.ptx.o OBJS-$(CONFIG_SCALE_NPP_FILTER) += vf_scale_npp.o scale_eval.o -OBJS-$(CONFIG_SCALE_QSV_FILTER) += vf_scale_qsv.o +OBJS-$(CONFIG_SCALE_QSV_FILTER) += vf_vpp_qsv.o OBJS-$(CONFIG_SCALE_VAAPI_FILTER)+= vf_scale_vaapi.o scale_eval.o vaapi_vpp.o OBJS-$(CONFIG_SCALE_VULKAN_FILTER) += vf_scale_vulkan.o vulkan.o OBJS-$(CONFIG_SCALE2REF_FILTER) += vf_scale.o scale_eval.o diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c deleted file mode 100644 index f8e937e40e..00 --- a/libavfilter/vf_scale_qsv.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * 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 - */ - -/** - * @file - * scale video filter - QSV - */ - -#include - -#include -#include - -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/hwcontext.h" -#include "libavutil/hwcontext_qsv.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/time.h" -#include "libavfilter/qsvvpp.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -static const char *const var_names[] = { -"in_w", "iw", -"in_h", "ih", -"out_w", "ow", -"out_h", "oh", -"a", "dar", -"sar", -NULL -}; - -enum var_name { -VAR_IN_W, VAR_IW, -VAR_IN_H, VAR_IH, -VAR_OUT_W, VAR_OW, -VAR_OUT_H, VAR_OH, -VAR_A, VAR_DAR, -VAR_SAR, -VARS_NB -}; - -#define QSV_HAVE_SCALING_CONFIG QSV_VERSION_ATLEAST(1, 19) - -typedef struct QSVScaleContext { -QSVVPPContext qsv; - -#if QSV_HAVE_SCALING_CONFIG -mfxExtVPPScaling scale_conf; -#endif -int mode; - -/** - * New dimensions. Special values are: - * 0 = original width/height - * -1 = keep original aspect - */ -int w, h; - -/** - * Output sw format. AV_PIX_FMT_NONE for no conversion. - */ -enum AVPixelFormat format; - -char *w_expr; ///< width expression string -char *h_expr; ///< height expression string -char *format_str; -} QSVScaleContext; - -static av_cold int qsvscale_init(AVFilterContext *ctx) -{ -QSVScaleContext *s = ctx->priv; - -if (!strcmp(s->format_str, "same")) { -s->format = AV_PIX_FMT_NONE; -} else { -s->format = av_get_pix_fmt(s->format_str); -if (s->format == AV_PIX_FMT_NONE) { -av_log(ctx, AV_LOG_ERROR, "Unrecognized pixel format: %s\n", s->format_str); -return AVERROR(EINVAL); -} -} - -return 0; -} - -static av_cold void qsvscale_uninit(AVFilterContext *ctx) -{ -ff_qsvvpp_close(ctx); -} - -static int qsvscale_query_formats(AVFilterContext *ctx) -{ -static const enum AVPixelFormat pixel_formats[] = { -AV_PIX_FMT_QSV, AV_PIX_FMT_NONE, -}; -AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats); -int ret; - -if ((ret = ff_set_common_formats(ctx, pix_fmts)) < 0) -return ret; - -return 0; -} - -static int qsvscale_config_props(AVFilterLink *outlink) -{ -AVFilterContext *ctx = outlink->src; -AVFilterLink *inlink = outlink->src->inputs[0]; -QSVScaleContext *s = ctx->priv; -QSVVPPParamparam = { NULL }; -#if QSV_HAVE_SCALING_CONFIG -mfxEx
[FFmpeg-devel] [PATCH v3 09/22] lavfi/vpp_qsv: add vpp_preinit callback
Set the expected default value for options in this callback, hence we have the right values even if these options are not included in the option arrray. This is in preparation for re-using VPPContext but with a different option array for other QSV filters --- libavfilter/vf_vpp_qsv.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index fd45c4f352..fb950001c0 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -256,6 +256,19 @@ release: return ret; } +static av_cold int vpp_preinit(AVFilterContext *ctx) +{ +VPPContext *vpp = ctx->priv; +/* For AV_OPT_TYPE_STRING options, NULL is handled in other way so + * we needn't set default value here + */ +vpp->saturation = 1.0; +vpp->contrast = 1.0; +vpp->transpose = -1; + +return 0; +} + static av_cold int vpp_init(AVFilterContext *ctx) { VPPContext *vpp = ctx->priv; @@ -637,6 +650,7 @@ const AVFilter ff_vf_vpp_qsv = { .description = NULL_IF_CONFIG_SMALL("Quick Sync Video VPP."), .priv_size = sizeof(VPPContext), .query_formats = query_formats, +.preinit = vpp_preinit, .init = vpp_init, .uninit= vpp_uninit, .inputs= vpp_inputs, -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 11/22] lavfi/vpp_qsv: factor common QSV filter definition
--- libavfilter/vf_vpp_qsv.c | 195 +-- 1 file changed, 86 insertions(+), 109 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index dd3afb5e10..03785e9398 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -105,44 +105,6 @@ typedef struct VPPContext{ int scaling_mode; } VPPContext; -static const AVOption options[] = { -{ "deinterlace", "deinterlace mode: 0=off, 1=bob, 2=advanced", OFFSET(deinterlace), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MFX_DEINTERLACING_ADVANCED, .flags = FLAGS, "deinterlace" }, -{ "bob", "Bob deinterlace mode.", 0, AV_OPT_TYPE_CONST,{ .i64 = MFX_DEINTERLACING_BOB }, .flags = FLAGS, "deinterlace" }, -{ "advanced","Advanced deinterlace mode. ",0, AV_OPT_TYPE_CONST,{ .i64 = MFX_DEINTERLACING_ADVANCED }, .flags = FLAGS, "deinterlace" }, - -{ "denoise", "denoise level [0, 100]", OFFSET(denoise), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS }, -{ "detail", "enhancement level [0, 100]", OFFSET(detail), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS }, -{ "framerate", "output framerate", OFFSET(framerate), AV_OPT_TYPE_RATIONAL, { .dbl = 0.0 },0, DBL_MAX, .flags = FLAGS }, -{ "procamp", "Enable ProcAmp", OFFSET(procamp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS}, -{ "hue", "ProcAmp hue", OFFSET(hue), AV_OPT_TYPE_FLOAT,{ .dbl = 0.0 }, -180.0, 180.0, .flags = FLAGS}, -{ "saturation", "ProcAmp saturation", OFFSET(saturation), AV_OPT_TYPE_FLOAT,{ .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS}, -{ "contrast","ProcAmp contrast", OFFSET(contrast), AV_OPT_TYPE_FLOAT,{ .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS}, -{ "brightness", "ProcAmp brightness", OFFSET(brightness), AV_OPT_TYPE_FLOAT,{ .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS}, - -{ "transpose", "set transpose direction", OFFSET(transpose), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, FLAGS, "transpose"}, -{ "cclock_hflip", "rotate counter-clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" }, -{ "clock", "rotate clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK }, .flags=FLAGS, .unit = "transpose" }, -{ "cclock","rotate counter-clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK }, .flags=FLAGS, .unit = "transpose" }, -{ "clock_hflip", "rotate clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" }, -{ "reversal", "rotate by half-turn", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_REVERSAL}, .flags=FLAGS, .unit = "transpose" }, -{ "hflip", "flip horizontally", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_HFLIP }, .flags=FLAGS, .unit = "transpose" }, -{ "vflip", "flip vertically", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_VFLIP }, .flags=FLAGS, .unit = "transpose" }, - -{ "cw", "set the width crop area expression", OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, 0, 0, FLAGS }, -{ "ch", "set the height crop area expression", OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, 0, 0, FLAGS }, -{ "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, 0, 0, FLAGS }, -{ "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, 0, 0, FLAGS }, - -{ "w", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "width", "Output video width(0=input video width, -1=keep input video aspect)", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS }, -{ "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, -{ "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, -{ "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, -{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS }, - -{ NULL } -}; - static co
[FFmpeg-devel] [PATCH v3 17/22] lavfi/vpp_qsv: check output format string against NULL pointer
This is in preparation for re-using VPPContext but with a different option array for deinterlacing_qsv filter --- libavfilter/vf_vpp_qsv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index cdf1f61b0f..45ac761d06 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -235,7 +235,7 @@ static av_cold int vpp_init(AVFilterContext *ctx) { VPPContext *vpp = ctx->priv; -if (!strcmp(vpp->output_format_str, "same")) { +if (!vpp->output_format_str || !strcmp(vpp->output_format_str, "same")) { vpp->out_format = AV_PIX_FMT_NONE; } else { vpp->out_format = av_get_pix_fmt(vpp->output_format_str); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v3 18/22] lavfi/deinterlace_qsv: simplify deinterlace_qsv filter
Like what we did for scale_qsv filter, we use QSVVPPContext as a base context to manage MFX session for deinterlace_qsv filter --- libavfilter/vf_deinterlace_qsv.c | 492 ++- 1 file changed, 30 insertions(+), 462 deletions(-) diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c index 3c2d87c7c8..50ff553e6a 100644 --- a/libavfilter/vf_deinterlace_qsv.c +++ b/libavfilter/vf_deinterlace_qsv.c @@ -42,34 +42,10 @@ #include "internal.h" #include "video.h" -enum { -QSVDEINT_MORE_OUTPUT = 1, -QSVDEINT_MORE_INPUT, -}; - typedef struct QSVDeintContext { -const AVClass *class; - -AVBufferRef *hw_frames_ctx; -/* a clone of the main session, used internally for deinterlacing */ -mfxSession session; - -mfxMemId *mem_ids; -intnb_mem_ids; - -mfxFrameSurface1 **surface_ptrs; -int nb_surface_ptrs; +QSVVPPContext qsv; -mfxExtOpaqueSurfaceAlloc opaque_alloc; -mfxExtVPPDeinterlacing deint_conf; -mfxExtBuffer*ext_buffers[2]; -int num_ext_buffers; - -QSVFrame *work_frames; - -int64_t last_pts; - -int eof; +mfxExtVPPDeinterlacing deint_conf; /* option for Deinterlacing algorithm to be used */ int mode; @@ -77,28 +53,7 @@ typedef struct QSVDeintContext { static av_cold void qsvdeint_uninit(AVFilterContext *ctx) { -QSVDeintContext *s = ctx->priv; -QSVFrame *cur; - -if (s->session) { -MFXClose(s->session); -s->session = NULL; -} -av_buffer_unref(&s->hw_frames_ctx); - -cur = s->work_frames; -while (cur) { -s->work_frames = cur->next; -av_frame_free(&cur->frame); -av_freep(&cur); -cur = s->work_frames; -} - -av_freep(&s->mem_ids); -s->nb_mem_ids = 0; - -av_freep(&s->surface_ptrs); -s->nb_surface_ptrs = 0; +ff_qsvvpp_close(ctx); } static int qsvdeint_query_formats(AVFilterContext *ctx) @@ -115,441 +70,54 @@ static int qsvdeint_query_formats(AVFilterContext *ctx) return 0; } -static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, - mfxFrameAllocResponse *resp) -{ -AVFilterContext *ctx = pthis; -QSVDeintContext *s = ctx->priv; - -if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || -!(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || -!(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) -return MFX_ERR_UNSUPPORTED; - -resp->mids = s->mem_ids; -resp->NumFrameActual = s->nb_mem_ids; - -return MFX_ERR_NONE; -} - -static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) -{ -return MFX_ERR_NONE; -} - -static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) -{ -return MFX_ERR_UNSUPPORTED; -} - -static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) -{ -return MFX_ERR_UNSUPPORTED; -} - -static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) -{ -*hdl = mid; -return MFX_ERR_NONE; -} - -static const mfxHandleType handle_types[] = { -MFX_HANDLE_VA_DISPLAY, -MFX_HANDLE_D3D9_DEVICE_MANAGER, -MFX_HANDLE_D3D11_DEVICE, -}; - -static int init_out_session(AVFilterContext *ctx) -{ - -QSVDeintContext *s = ctx->priv; -AVHWFramesContext*hw_frames_ctx = (AVHWFramesContext*)s->hw_frames_ctx->data; -AVQSVFramesContext *hw_frames_hwctx = hw_frames_ctx->hwctx; -AVQSVDeviceContext*device_hwctx = hw_frames_ctx->device_ctx->hwctx; - -int opaque = !!(hw_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); - -mfxHDL handle = NULL; -mfxHandleType handle_type; -mfxVersion ver; -mfxIMPL impl; -mfxVideoParam par; -mfxStatus err; -int i; - -/* extract the properties of the "master" session given to us */ -err = MFXQueryIMPL(device_hwctx->session, &impl); -if (err == MFX_ERR_NONE) -err = MFXQueryVersion(device_hwctx->session, &ver); -if (err != MFX_ERR_NONE) { -av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n"); -return AVERROR_UNKNOWN; -} - -for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) { -err = MFXVideoCORE_GetHandle(device_hwctx->session, handle_types[i], &handle); -if (err == MFX_ERR_NONE) { -handle_type = handle_types[i]; -break; -} -} - -if (err < 0) -return ff_qsvvpp_print_error(ctx, err, "Error getting the session handle"); -else if (err > 0) { -ff_qsvvpp_print_warning(ctx, err, "Warning in getting the session handle"); -return AVERROR_UNKNOWN; -} - -/* create a "slave" session with those same properties, to be used for - * actual deinterlacing */ -err = MFXInit(impl, &ver, &s->session); -if (err < 0) -return ff_qsvvpp_print_error(ctx, err, "Error initializing a session for