Re: [FFmpeg-devel] [PATCH 1/3] lavc/qsvdec: add support for gpu_copy

2019-04-07 Thread Fu, Linjie
> -Original Message-
> From: Fu, Linjie
> Sent: Tuesday, March 26, 2019 13:38
> To: ffmpeg-devel@ffmpeg.org
> Cc: Fu, Linjie ; ChaoX A Liu 
> Subject: [PATCH 1/3] lavc/qsvdec: add support for gpu_copy
> 
> Add support for GPU copy when QSV decoders works in system memory
> mode.
> However, memory must be sequent and aligned with 128x64 to enable this
> feature.(first introduced in FFmpeg 3.3.1)
> 
> GPUCopy = MFX_GPUCOPY_ON leads to performance improvement up to
> x10.
> 
> CMD:
> ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv
> -gpu_copy on -i input.h264 -pix_fmt yuv420p out.yuv
> 
> 
> Signed-off-by: Linjie Fu 
> Signed-off-by: ChaoX A Liu 
> ---
>  libavcodec/qsv.c  | 27 +---
>  libavcodec/qsv_internal.h |  6 ++---
>  libavcodec/qsvdec.c   | 53 ++
> -
>  libavcodec/qsvdec.h   |  2 ++
>  libavcodec/qsvdec_h2645.c | 10 
>  libavcodec/qsvdec_other.c |  5 
>  libavcodec/qsvenc.c   |  7 +++---
>  7 files changed, 89 insertions(+), 21 deletions(-)
> 
> diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
> index bb0d79588c..40e6c677cb 100644
> --- a/libavcodec/qsv.c
> +++ b/libavcodec/qsv.c
> @@ -277,15 +277,19 @@ load_plugin_fail:
>  }
> 
>  int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession
> *session,
> - const char *load_plugins)
> + const char *load_plugins, int gpu_copy)
>  {
> -mfxIMPL impl   = MFX_IMPL_AUTO_ANY;
> -mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
> +mfxIMPL  impl = MFX_IMPL_AUTO_ANY;
> +mfxVersionver = { { QSV_VERSION_MINOR,
> QSV_VERSION_MAJOR } };
> +mfxInitParam init_par = { MFX_IMPL_AUTO_ANY };
> 
>  const char *desc;
>  int ret;
> 
> -ret = MFXInit(impl, &ver, session);
> +init_par.GPUCopy= gpu_copy;
> +init_par.Implementation = impl;
> +init_par.Version= ver;
> +ret = MFXInitEx(init_par, session);
>  if (ret < 0)
>  return ff_qsv_print_error(avctx, ret,
>"Error initializing an internal MFX 
> session");
> @@ -571,7 +575,8 @@ static mfxStatus qsv_frame_get_hdl(mfxHDL pthis,
> mfxMemId mid, mfxHDL *hdl)
>  }
> 
>  int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession
> *psession,
> -   AVBufferRef *device_ref, const char 
> *load_plugins)
> +   AVBufferRef *device_ref, const char 
> *load_plugins,
> +   int gpu_copy)
>  {
>  static const mfxHandleType handle_types[] = {
>  MFX_HANDLE_VA_DISPLAY,
> @@ -581,11 +586,12 @@ int ff_qsv_init_session_device(AVCodecContext
> *avctx, mfxSession *psession,
>  AVHWDeviceContext*device_ctx = (AVHWDeviceContext*)device_ref-
> >data;
>  AVQSVDeviceContext *device_hwctx = device_ctx->hwctx;
>  mfxSessionparent_session = device_hwctx->session;
> +mfxInitParaminit_par = { MFX_IMPL_AUTO_ANY };
> +mfxHDLhandle = NULL;
> 
>  mfxSessionsession;
>  mfxVersionver;
>  mfxIMPL   impl;
> -mfxHDLhandle = NULL;
>  mfxHandleType handle_type;
>  mfxStatus err;
> 
> @@ -611,7 +617,10 @@ int ff_qsv_init_session_device(AVCodecContext
> *avctx, mfxSession *psession,
> "from the session\n");
>  }
> 
> -err = MFXInit(impl, &ver, &session);
> +init_par.GPUCopy= gpu_copy;
> +init_par.Implementation = impl;
> +init_par.Version= ver;
> +err = MFXInitEx(init_par, &session);
>  if (err != MFX_ERR_NONE)
>  return ff_qsv_print_error(avctx, err,
>"Error initializing a child MFX session");
> @@ -642,7 +651,7 @@ int ff_qsv_init_session_device(AVCodecContext
> *avctx, mfxSession *psession,
> 
>  int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession
> *psession,
> QSVFramesContext *qsv_frames_ctx,
> -   const char *load_plugins, int opaque)
> +   const char *load_plugins, int opaque, int 
> gpu_copy)
>  {
>  mfxFrameAllocator frame_allocator = {
>  .pthis  = qsv_frames_ctx,
> @@ -662,7 +671,7 @@ int ff_qsv_init_session_frames(AVCodecContext
> *avctx, mfxSession *psession,
>  int ret;
> 
>  ret = ff_qsv_init_session_device(avctx, &session,
> - frames_ctx->device_ref, load_plugins);
> + frames_ctx->device_ref, load_plugins, 
> gpu_copy);
>  if (ret < 0)
>  return ret;
> 
> diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
> index 394c558883..8be6c3757c 100644
> --- a/libavcodec/qsv_internal.h
> +++ b/libavcodec/qsv_internal.h
> @@ -95,14 +95,14 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format,
> uint32_t *four

[FFmpeg-devel] [PATCH 1/3] lavc/qsvdec: add support for gpu_copy

2019-03-25 Thread Linjie Fu
Add support for GPU copy when QSV decoders works in system memory mode.
However, memory must be sequent and aligned with 128x64 to enable this
feature.(first introduced in FFmpeg 3.3.1)

GPUCopy = MFX_GPUCOPY_ON leads to performance improvement up to x10.

CMD:
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv
-gpu_copy on -i input.h264 -pix_fmt yuv420p out.yuv


Signed-off-by: Linjie Fu 
Signed-off-by: ChaoX A Liu 
---
 libavcodec/qsv.c  | 27 +---
 libavcodec/qsv_internal.h |  6 ++---
 libavcodec/qsvdec.c   | 53 ++-
 libavcodec/qsvdec.h   |  2 ++
 libavcodec/qsvdec_h2645.c | 10 
 libavcodec/qsvdec_other.c |  5 
 libavcodec/qsvenc.c   |  7 +++---
 7 files changed, 89 insertions(+), 21 deletions(-)

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index bb0d79588c..40e6c677cb 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -277,15 +277,19 @@ load_plugin_fail:
 }
 
 int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
- const char *load_plugins)
+ const char *load_plugins, int gpu_copy)
 {
-mfxIMPL impl   = MFX_IMPL_AUTO_ANY;
-mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
+mfxIMPL  impl = MFX_IMPL_AUTO_ANY;
+mfxVersionver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
+mfxInitParam init_par = { MFX_IMPL_AUTO_ANY };
 
 const char *desc;
 int ret;
 
-ret = MFXInit(impl, &ver, session);
+init_par.GPUCopy= gpu_copy;
+init_par.Implementation = impl;
+init_par.Version= ver;
+ret = MFXInitEx(init_par, session);
 if (ret < 0)
 return ff_qsv_print_error(avctx, ret,
   "Error initializing an internal MFX 
session");
@@ -571,7 +575,8 @@ static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId 
mid, mfxHDL *hdl)
 }
 
 int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
-   AVBufferRef *device_ref, const char 
*load_plugins)
+   AVBufferRef *device_ref, const char 
*load_plugins,
+   int gpu_copy)
 {
 static const mfxHandleType handle_types[] = {
 MFX_HANDLE_VA_DISPLAY,
@@ -581,11 +586,12 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, 
mfxSession *psession,
 AVHWDeviceContext*device_ctx = (AVHWDeviceContext*)device_ref->data;
 AVQSVDeviceContext *device_hwctx = device_ctx->hwctx;
 mfxSessionparent_session = device_hwctx->session;
+mfxInitParaminit_par = { MFX_IMPL_AUTO_ANY };
+mfxHDLhandle = NULL;
 
 mfxSessionsession;
 mfxVersionver;
 mfxIMPL   impl;
-mfxHDLhandle = NULL;
 mfxHandleType handle_type;
 mfxStatus err;
 
@@ -611,7 +617,10 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, 
mfxSession *psession,
"from the session\n");
 }
 
-err = MFXInit(impl, &ver, &session);
+init_par.GPUCopy= gpu_copy;
+init_par.Implementation = impl;
+init_par.Version= ver;
+err = MFXInitEx(init_par, &session);
 if (err != MFX_ERR_NONE)
 return ff_qsv_print_error(avctx, err,
   "Error initializing a child MFX session");
@@ -642,7 +651,7 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, 
mfxSession *psession,
 
 int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *psession,
QSVFramesContext *qsv_frames_ctx,
-   const char *load_plugins, int opaque)
+   const char *load_plugins, int opaque, int 
gpu_copy)
 {
 mfxFrameAllocator frame_allocator = {
 .pthis  = qsv_frames_ctx,
@@ -662,7 +671,7 @@ int ff_qsv_init_session_frames(AVCodecContext *avctx, 
mfxSession *psession,
 int ret;
 
 ret = ff_qsv_init_session_device(avctx, &session,
- frames_ctx->device_ref, load_plugins);
+ frames_ctx->device_ref, load_plugins, 
gpu_copy);
 if (ret < 0)
 return ret;
 
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index 394c558883..8be6c3757c 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -95,14 +95,14 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t 
*fourcc);
 enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type);
 
 int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
- const char *load_plugins);
+ const char *load_plugins, int gpu_copy);
 
 int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
-   AVBufferRef *device_ref, const char 
*load_plugins);
+