[libav-devel] [PATCH v2] qsv: adding Multi Frame Encode support

Li, Zhong zhong.li at intel.com
Wed Apr 4 08:54:06 CEST 2018


LGTM

> -----Original Message-----
> From: libav-devel [mailto:libav-devel-bounces at libav.org] On Behalf Of
> Maxym Dmytrychenko
> Sent: Monday, April 2, 2018 9:17 PM
> To: libav-devel at libav.org
> Subject: [libav-devel] [PATCH v2] qsv: adding Multi Frame Encode support
> 
> Starting from API 1.25 helps to improve performance of the simultaneous
> encode, 1:N scenario, like:
> 
> ./avconv  -y -hwaccel qsv -c:v h264_qsv -r 30000/1001 -i
> ~/bbb_sunflower_1080p_60fps_normal.mp4  -vframes 600 -an \
>     -filter_complex "split=2[s1][s2]; [s1]scale_qsv=1280:720[o1];
> [s2]scale_qsv=960:540[o2]" \
>     -map [o1] -c:v h264_qsv -b:v 3200k -minrate 3200k -maxrate 3200k -f
> rawvideo /tmp/3200a.264 \
>     -map [o2] -c:v h264_qsv -b:v 1750k -minrate 1750k -maxrate 1750k -f
> rawvideo /tmp/1750a.264
> ---
>  libavcodec/qsv.c                 | 10 ++++++----
>  libavcodec/qsv_internal.h        |  4 ++++
>  libavcodec/qsvenc.c              | 16 +++++++++++++++-
>  libavcodec/qsvenc.h              | 12 ++++++++++--
>  libavcodec/qsvenc_h264.c         |  4 ++++
>  libavfilter/qsvvpp.c             |  9 ++++++---
>  libavfilter/qsvvpp.h             |  8 ++++++++
>  libavfilter/vf_deinterlace_qsv.c |  7 +++++++
>  libavfilter/vf_scale_qsv.c       |  7 +++++++
>  libavutil/hwcontext_qsv.c        |  5 +++++
>  10 files changed, 72 insertions(+), 10 deletions(-)
> 
> diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index e78633d62..bab32836e
> 100644
> --- a/libavcodec/qsv.c
> +++ b/libavcodec/qsv.c
> @@ -593,10 +593,12 @@ int ff_qsv_init_session_device(AVCodecContext
> *avctx, mfxSession *psession,
>                                        "Error setting a HW
> handle");
>      }
> 
> -    err = MFXJoinSession(parent_session, session);
> -    if (err != MFX_ERR_NONE)
> -        return ff_qsv_print_error(avctx, err,
> -                                  "Error joining session");
> +    if (QSV_RUNTIME_VERSION_ATLEAST(ver, 1, 25)) {
> +        err = MFXJoinSession(parent_session, session);
> +        if (err != MFX_ERR_NONE)
> +            return ff_qsv_print_error(avctx, err,
> +                                      "Error joining session");
> +    }
> 
>      ret = qsv_load_plugins(session, load_plugins, avctx);
>      if (ret < 0) {
> diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index
> 975c8de44..d2a18eb06 100644
> --- a/libavcodec/qsv_internal.h
> +++ b/libavcodec/qsv_internal.h
> @@ -36,6 +36,10 @@
>      (MFX_VERSION_MAJOR > (MAJOR) ||         \
>       MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >=
> (MINOR))
> 
> +#define QSV_RUNTIME_VERSION_ATLEAST(MFX_VERSION, MAJOR,
> MINOR) \
> +    (MFX_VERSION.Major > (MAJOR)) ||                           \
> +    (MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >=
> (MINOR))
> +
>  typedef struct QSVMid {
>      AVBufferRef *hw_frames_ref;
>      mfxHDL handle;
> diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index
> f6b1a0d67..a8b446c5b 100644
> --- a/libavcodec/qsvenc.c
> +++ b/libavcodec/qsvenc.c
> @@ -135,7 +135,7 @@ static void dump_video_param(AVCodecContext
> *avctx, QSVEncContext *q,  #if QSV_HAVE_CO2
>      mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
>  #endif
> -#if QSV_HAVE_CO3
> +#if QSV_HAVE_CO3 && QSV_HAVE_QVBR
>      mfxExtCodingOption3 *co3 = (mfxExtCodingOption3*)coding_opts[2];
>  #endif
> 
> @@ -656,6 +656,20 @@ FF_ENABLE_DEPRECATION_WARNINGS
> 
>              q->extparam_internal[q->nb_extparam_internal++] =
> (mfxExtBuffer *)&q->extco2;
>          }
> +#endif
> +#if QSV_HAVE_MF
> +        if (avctx->codec_id == AV_CODEC_ID_H264) {
> +            mfxVersion    ver;
> +            ret = MFXQueryVersion(q->session,&ver);
> +            if (ret >= MFX_ERR_NONE &&
> QSV_RUNTIME_VERSION_ATLEAST(ver, 1, 25)) {
> +                q->extmfp.Header.BufferId     =
> MFX_EXTBUFF_MULTI_FRAME_PARAM;
> +                q->extmfp.Header.BufferSz     = sizeof(q->extmfp);
> +
> +                q->extmfp.MFMode = q->mfmode;
> +                av_log(avctx,AV_LOG_VERBOSE,"MFMode:%d\n",
> q->extmfp.MFMode);
> +                q->extparam_internal[q->nb_extparam_internal++] =
> (mfxExtBuffer *)&q->extmfp;
> +            }
> +        }
>  #endif
>      }
> 
> diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index
> ab5579595..a7fc57bb4 100644
> --- a/libavcodec/qsvenc.h
> +++ b/libavcodec/qsvenc.h
> @@ -50,11 +50,13 @@
>  #define QSV_HAVE_ICQ    QSV_VERSION_ATLEAST(1, 8)
>  #define QSV_HAVE_VCM    QSV_VERSION_ATLEAST(1, 8)
>  #define QSV_HAVE_QVBR   QSV_VERSION_ATLEAST(1, 11)
> +#define QSV_HAVE_MF     0
>  #else
>  #define QSV_HAVE_AVBR   0
>  #define QSV_HAVE_ICQ    0
>  #define QSV_HAVE_VCM    0
>  #define QSV_HAVE_QVBR   0
> +#define QSV_HAVE_MF     QSV_VERSION_ATLEAST(1, 25)
>  #endif
> 
>  #if !QSV_HAVE_LA_DS
> @@ -109,12 +111,15 @@ typedef struct QSVEncContext {  #if
> QSV_HAVE_CO2
>      mfxExtCodingOption2 extco2;
>  #endif
> -
> +#if QSV_HAVE_MF
> +    mfxExtMultiFrameParam   extmfp;
> +    mfxExtMultiFrameControl extmfc;
> +#endif
>      mfxExtOpaqueSurfaceAlloc opaque_alloc;
>      mfxFrameSurface1       **opaque_surfaces;
>      AVBufferRef             *opaque_alloc_buf;
> 
> -    mfxExtBuffer  *extparam_internal[2 + QSV_HAVE_CO2];
> +    mfxExtBuffer  *extparam_internal[2 + QSV_HAVE_CO2 +
> (QSV_HAVE_MF *
> + 2)];
>      int         nb_extparam_internal;
> 
>      mfxExtBuffer **extparam;
> @@ -156,6 +161,9 @@ typedef struct QSVEncContext {
>      int int_ref_qp_delta;
>      int recovery_point_sei;
> 
> +#if QSV_HAVE_MF
> +    int mfmode;
> +#endif
>      char *load_plugins;
>  } QSVEncContext;
> 
> diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c index
> 634a7d3f9..ae00ff8d5 100644
> --- a/libavcodec/qsvenc_h264.c
> +++ b/libavcodec/qsvenc_h264.c
> @@ -93,6 +93,10 @@ static const AVOption options[] = {
> 
>      { "aud", "Insert the Access Unit Delimiter NAL", OFFSET(qsv.aud),
> AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE},
> 
> +#if QSV_HAVE_MF
> +    { "mfmode", "Multi-Frame Mode", OFFSET(qsv.mfmode),
> +AV_OPT_TYPE_INT, { .i64 = MFX_MF_AUTO }, 0, INT_MAX, VE }, #endif
> +
>      { NULL },
>  };
> 
> diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index
> a96cfa65d..f704517ae 100644
> --- a/libavfilter/qsvvpp.c
> +++ b/libavfilter/qsvvpp.c
> @@ -515,9 +515,12 @@ static int init_vpp_session(AVFilterContext *avctx,
> QSVVPPContext *s)
>          if (ret != MFX_ERR_NONE)
>              return AVERROR_UNKNOWN;
>      }
> -    ret = MFXJoinSession(device_hwctx->session, s->session);
> -    if (ret != MFX_ERR_NONE)
> -        return AVERROR_UNKNOWN;
> +
> +    if (QSV_RUNTIME_VERSION_ATLEAST(ver, 1, 25)) {
> +        ret = MFXJoinSession(device_hwctx->session, s->session);
> +        if (ret != MFX_ERR_NONE)
> +            return AVERROR_UNKNOWN;
> +    }
> 
>      if (IS_OPAQUE_MEMORY(s->in_mem_mode) ||
> IS_OPAQUE_MEMORY(s->out_mem_mode)) {
>          s->opaque_alloc.In.Surfaces   = s->surface_ptrs_in;
> diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h index
> 082c0a899..d25ea69e5 100644
> --- a/libavfilter/qsvvpp.h
> +++ b/libavfilter/qsvvpp.h
> @@ -31,6 +31,14 @@
>  #define FF_INLINK_IDX(link)  ((int)((link)->dstpad - (link)->dst->input_pads))
> #define FF_OUTLINK_IDX(link) ((int)((link)->srcpad -
> (link)->src->output_pads))
> 
> +#define QSV_VERSION_ATLEAST(MAJOR, MINOR)   \
> +    (MFX_VERSION_MAJOR > (MAJOR) ||         \
> +     MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >=
> (MINOR))
> +
> +#define QSV_RUNTIME_VERSION_ATLEAST(MFX_VERSION, MAJOR,
> MINOR) \
> +    (MFX_VERSION.Major > (MAJOR)) ||                           \
> +    (MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >=
> (MINOR))
> +
>  typedef struct QSVVPPContext QSVVPPContext;
> 
>  typedef struct QSVVPPCrop {
> diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c
> index 2360491d3..bb26a4dbf 100644
> --- a/libavfilter/vf_deinterlace_qsv.c
> +++ b/libavfilter/vf_deinterlace_qsv.c
> @@ -35,6 +35,7 @@
>  #include "libavutil/opt.h"
>  #include "libavutil/pixdesc.h"
>  #include "libavutil/time.h"
> +#include "libavfilter/qsvvpp.h"
> 
>  #include "avfilter.h"
>  #include "formats.h"
> @@ -214,6 +215,12 @@ static int init_out_session(AVFilterContext *ctx)
>              return AVERROR_UNKNOWN;
>      }
> 
> +    if (QSV_RUNTIME_VERSION_ATLEAST(ver, 1, 25)) {
> +        err = MFXJoinSession(device_hwctx->session, s->session);
> +        if (err != MFX_ERR_NONE)
> +            return AVERROR_UNKNOWN;
> +    }
> +
>      memset(&par, 0, sizeof(par));
> 
>      s->deint_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING;
> diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c index
> c568e9625..381844cdc 100644
> --- a/libavfilter/vf_scale_qsv.c
> +++ b/libavfilter/vf_scale_qsv.c
> @@ -36,6 +36,7 @@
>  #include "libavutil/opt.h"
>  #include "libavutil/pixdesc.h"
>  #include "libavutil/time.h"
> +#include "libavfilter/qsvvpp.h"
> 
>  #include "avfilter.h"
>  #include "formats.h"
> @@ -313,6 +314,12 @@ static int init_out_session(AVFilterContext *ctx)
>              return AVERROR_UNKNOWN;
>      }
> 
> +    if (QSV_RUNTIME_VERSION_ATLEAST(ver, 1, 25)) {
> +        err = MFXJoinSession(device_hwctx->session, s->session);
> +            if (err != MFX_ERR_NONE)
> +                return AVERROR_UNKNOWN;
> +    }
> +
>      memset(&par, 0, sizeof(par));
> 
>      if (opaque) {
> diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index
> f5d78d059..b3eb4a3ea 100644
> --- a/libavutil/hwcontext_qsv.c
> +++ b/libavutil/hwcontext_qsv.c
> @@ -1058,6 +1058,11 @@ static int
> qsv_device_derive_from_child(AVHWDeviceContext *ctx,
>          goto fail;
>      }
> 
> +    ret = MFXQueryVersion(hwctx->session,&ver);
> +    if (ret == MFX_ERR_NONE) {
> +        av_log(ctx, AV_LOG_VERBOSE, "MFX compile/runtime
> API: %d.%d/%d.%d\n",
> +               MFX_VERSION_MAJOR, MFX_VERSION_MINOR,
> ver.Major, ver.Minor);
> +    }
>      return 0;
> 
>  fail:
> --
> 2.14.3 (Apple Git-98)
> 
> _______________________________________________
> libav-devel mailing list
> libav-devel at libav.org
> https://lists.libav.org/mailman/listinfo/libav-devel


More information about the libav-devel mailing list