LGTM
> -----Original Message----- > From: libav-devel [mailto:libav-devel-boun...@libav.org] On Behalf Of > Maxym Dmytrychenko > Sent: Monday, April 2, 2018 9:17 PM > To: libav-devel@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@libav.org > https://lists.libav.org/mailman/listinfo/libav-devel _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel