[FFmpeg-devel] [PATCH v5 00/10] make QSV works with the Intel's oneVPL

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-08 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2021-10-15 Thread Haihao Xiang
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

2018-11-20 Thread Haihao Xiang
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

2021-03-22 Thread Haihao Xiang
---
 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

2021-03-22 Thread Haihao Xiang
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

2021-04-08 Thread Haihao Xiang
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

2021-04-08 Thread Haihao Xiang
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

2021-04-08 Thread Haihao Xiang
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

2020-06-18 Thread Haihao Xiang
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

2020-06-18 Thread Haihao Xiang
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

2021-04-24 Thread Haihao Xiang
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

2021-04-24 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
---
 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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
---
 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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-13 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
---
 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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
---
 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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-05-16 Thread Haihao Xiang
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

2021-06-08 Thread Haihao Xiang
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

2021-06-08 Thread Haihao Xiang
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

2021-06-09 Thread Haihao Xiang
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

2021-06-10 Thread Haihao Xiang
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

2021-06-10 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
---
 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

2021-06-14 Thread Haihao Xiang
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

2021-06-14 Thread Haihao Xiang
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

  1   2   3   >