From cca5e4f040971db6de0bfe6968f00c021d8a9c42 Mon Sep 17 00:00:00 2001 From: Maxym Dmytrychenko Date: Mon, 2 Apr 2018 15:17:23 +0200 Subject: 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 Signed-off-by: Maxym Dmytrychenko --- libavcodec/qsv.c | 10 ++++++---- libavcodec/qsv_internal.h | 4 ++++ libavcodec/qsvenc.c | 16 +++++++++++++++- libavcodec/qsvenc.h | 12 ++++++++++-- libavcodec/qsvenc_h264.c | 4 ++++ 5 files changed, 39 insertions(+), 7 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index e578ab1..a9b3c59 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -617,10 +617,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 07ddc59..3cd8f18 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 f6b1a0d..a8b446c 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 @@ -657,6 +657,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 } if (!check_enc_param(avctx,q)) { diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index ab55795..a7fc57b 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 634a7d3..ae00ff8 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 }, }; -- cgit v1.1