mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-26 09:12:33 +00:00
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 <maxim.d33@gmail.com>
This commit is contained in:
parent
29a8ed7663
commit
cca5e4f040
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 },
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user