[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.
From: ChaoX A Liu Signed-off-by: ChaoX A Liu --- 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_qsvvpp.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 { intfd_display; VADisplay va_display; #endif +intgpu_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 AVOptio
[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.
From: ChaoX A Liu Signed-off-by: ChaoX A Liu --- 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 { intfd_display; VADisplay va_display; #endif +intgpu_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 AVOptio