[FFmpeg-devel] [PATCH 6/6] lavc/qsv-lavc/vpp: Promote gpu_copy to be a selectable parameter. GPU-copy is defaultly closed because it seems to be unstable.
Nablet Developer
sdk at nablet.com
Tue Aug 16 13:10:07 EEST 2016
From: ChaoX A Liu <chaox.a.liu at intel.com>
Signed-off-by: ChaoX A Liu <chaox.a.liu at intel.com>
---
libavcodec/qsv.c | 7 ++++++-
libavcodec/qsv_internal.h | 1 +
libavcodec/qsvdec.c | 22 +++++++++++++++++-----
libavcodec/qsvdec_h2645.c | 12 ++++++++++++
libavcodec/qsvdec_mpeg2.c | 6 ++++++
libavcodec/qsvdec_vc1.c | 6 ++++++
libavcodec/qsvenc.h | 4 ++++
libavfilter/vf_vpp.c | 8 +++++++-
8 files changed, 59 insertions(+), 7 deletions(-)
diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index c180ca8..c61a29c 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -172,11 +172,16 @@ int ff_qsv_init_internal_session(void *avctx, QSVSession *qs)
{
mfxIMPL impl = MFX_IMPL_AUTO_ANY;
mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
+ mfxInitParam par;
const char *desc;
int ret;
- ret = MFXInit(impl, &ver, &qs->session);
+ memset(&par, 0, sizeof(par));
+ par.Implementation = impl;
+ par.Version = ver;
+ par.GPUCopy = qs->gpu_copy;
+ ret = MFXInitEx(par, &qs->session);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n");
return ff_qsv_error(ret);
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index 58589df..39778a9 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -73,6 +73,7 @@ typedef struct QSVSession {
int fd_display;
VADisplay va_display;
#endif
+ int gpu_copy;
} QSVSession;
/**
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 2075a23..08a5eaa 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -176,13 +176,25 @@ static int alloc_frame(AVCodecContext *avctx, QSVFrame *frame)
{
int ret;
- ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
- if (ret < 0)
- return ret;
-
- if (frame->frame->format == AV_PIX_FMT_QSV) {
+ if (avctx->pix_fmt == AV_PIX_FMT_QSV) {
+ ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
+ if (ret < 0)
+ return ret;
frame->surface = (mfxFrameSurface1*)frame->frame->data[3];
} else {
+ /*
+ * Align frame's width x height to 128x64.
+ * It's recommended to do so if GPU_Copy is turned on.
+ */
+ frame->frame->format = avctx->pix_fmt;
+ frame->frame->width = FFALIGN(avctx->width, 128);
+ frame->frame->height = FFALIGN(avctx->height, 64);
+ ret = av_frame_get_buffer(frame->frame, 64);
+ if (ret < 0)
+ return ret;
+ frame->frame->width = avctx->width;
+ frame->frame->height = avctx->height;
+
frame->surface_internal.Info.BitDepthLuma = 8;
frame->surface_internal.Info.BitDepthChroma = 8;
frame->surface_internal.Info.FourCC = MFX_FOURCC_NV12;
diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c
index 208302b..a4adc10 100755
--- a/libavcodec/qsvdec_h2645.c
+++ b/libavcodec/qsvdec_h2645.c
@@ -248,6 +248,12 @@ static const AVOption hevc_options[] = {
{ "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
+
+ { "gpu_copy", "Enable gpu copy in sysmem mode [default = off]", OFFSET(qsv.internal_qs.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_OFF }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, .flags = VD, "gpu_copy" },
+ { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, .flags = VD, "gpu_copy" },
+ { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, .flags = VD, "gpu_copy" },
+ { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, .flags = VD, "gpu_copy" },
+
{ NULL },
};
@@ -286,6 +292,12 @@ AVHWAccel ff_h264_qsv_hwaccel = {
static const AVOption options[] = {
{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD },
+
+ { "gpu_copy", "Enable gpu copy in sysmem mode [default = off]", OFFSET(qsv.internal_qs.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_OFF }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, .flags = VD, "gpu_copy" },
+ { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, .flags = VD, "gpu_copy" },
+ { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, .flags = VD, "gpu_copy" },
+ { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, .flags = VD, "gpu_copy" },
+
{ NULL },
};
diff --git a/libavcodec/qsvdec_mpeg2.c b/libavcodec/qsvdec_mpeg2.c
index 70ccbc5..5e2354a 100644
--- a/libavcodec/qsvdec_mpeg2.c
+++ b/libavcodec/qsvdec_mpeg2.c
@@ -72,6 +72,12 @@ AVHWAccel ff_mpeg2_qsv_hwaccel = {
#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD },
+
+ { "gpu_copy", "Enable gpu copy in sysmem mode [default = off]", OFFSET(qsv.internal_qs.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_OFF }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, .flags = VD, "gpu_copy" },
+ { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, .flags = VD, "gpu_copy" },
+ { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, .flags = VD, "gpu_copy" },
+ { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, .flags = VD, "gpu_copy" },
+
{ NULL },
};
diff --git a/libavcodec/qsvdec_vc1.c b/libavcodec/qsvdec_vc1.c
index fcf101f..4948b00 100644
--- a/libavcodec/qsvdec_vc1.c
+++ b/libavcodec/qsvdec_vc1.c
@@ -69,6 +69,12 @@ AVHWAccel ff_vc1_qsv_hwaccel = {
#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VD },
+
+ { "gpu_copy", "Enable gpu copy in sysmem mode [default = off]", OFFSET(qsv.internal_qs.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_OFF }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, .flags = VD, "gpu_copy" },
+ { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, .flags = VD, "gpu_copy" },
+ { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, .flags = VD, "gpu_copy" },
+ { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, .flags = VD, "gpu_copy" },
+
{ NULL },
};
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 2d7bd32..9510d5c 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -70,6 +70,10 @@
{ "adaptive_b", "Adaptive B-frame placement", OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
{ "b_strategy", "Strategy to choose between I/P/B-frames", OFFSET(qsv.b_strategy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
{ "cavlc", "Enable CAVLC", OFFSET(qsv.cavlc), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \
+{ "gpu_copy", "Enable gpu copy in sysmem mode [default = off]", OFFSET(qsv.internal_qs.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_OFF }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, .flags = VE, "gpu_copy" },\
+{ "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, .flags = VE, "gpu_copy" },\
+{ "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, .flags = VE, "gpu_copy" },\
+{ "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, .flags = VE, "gpu_copy" },\
typedef int SetEncodeCtrlCB (AVCodecContext *avctx,
const AVFrame *frame, mfxEncodeCtrl* enc_ctrl);
diff --git a/libavfilter/vf_vpp.c b/libavfilter/vf_vpp.c
index 5047a9a..80977af 100644
--- a/libavfilter/vf_vpp.c
+++ b/libavfilter/vf_vpp.c
@@ -127,6 +127,12 @@ static const AVOption vpp_options[] = {
{ "framerate", "output framerate", OFFSET(framerate), AV_OPT_TYPE_RATIONAL, { .dbl = 0.0 },0, DBL_MAX, .flags = FLAGS },
{ "async_depth", "Maximum processing parallelism [default = 4]", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, .flags = FLAGS },
{ "max_b_frames","Maximum number of b frames [default = 3]", OFFSET(max_b_frames), AV_OPT_TYPE_INT, { .i64 = 3 }, 0, INT_MAX, .flags = FLAGS },
+
+ { "gpu_copy", "Enable gpu copy in sysmem mode [default = off]", OFFSET(internal_qs.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_OFF }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, .flags = FLAGS, "gpu_copy" },
+ { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, .flags = FLAGS, "gpu_copy" },
+ { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, .flags = FLAGS, "gpu_copy" },
+ { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, .flags = FLAGS, "gpu_copy" },
+
{ NULL }
};
@@ -665,7 +671,7 @@ static AVFrame *vidmem_buffer_alloc(AVFilterContext *ctx, mfxFrameSurface1 *pSur
vidmem_buffer_free, NULL, 0);
if (!frame->buf[0]) {
av_frame_free(&frame);
- return AVERROR(ENOMEM);
+ return NULL;
}
frame->data[3] = frame->buf[0]->data;
--
2.5.0
More information about the ffmpeg-devel
mailing list