[FFmpeg-devel] [PATCH] lavc/vaapi_decode: Set surfaces reference pool size according to SPS for H.264/HEVC

Fu, Linjie linjie.fu at intel.com
Mon Nov 11 11:42:28 EET 2019


> -----Original Message-----
> From: Fu, Linjie <linjie.fu at intel.com>
> Sent: Wednesday, November 6, 2019 12:54
> To: ffmpeg-devel at ffmpeg.org
> Cc: Fu, Linjie <linjie.fu at intel.com>
> Subject: [PATCH] lavc/vaapi_decode: Set surfaces reference pool size
> according to SPS for H.264/HEVC
> 
> Set surfaces pool used for storing reference frames dynamically
> according to SPS.(reference framecount, reordered frame number, etc)
> 
> Compared to a fixed pool size for H.264 and HEVC, the usage of
> GPU memory could be improved.
> 
> CMD:
> ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128
>         -i bbb_sunflower_1080p_30fps_normal.mp4 -f null -
> Source:
>     https://download.blender.org/demo/movies/BBB/
> 
> GEM Object memory usage:
>     watch cat /sys/kernel/debug/dri/0/i915_gem_objects
> Before:
>     ~112M
> After:
>     ~80M
> 
> Signed-off-by: Linjie Fu <linjie.fu at intel.com>
> ---
>  libavcodec/vaapi_decode.c | 39 ++++++++++++++++++---------------------
>  libavcodec/vaapi_decode.h |  3 +++
>  libavcodec/vaapi_h264.c   | 11 ++++++++++-
>  libavcodec/vaapi_hevc.c   | 11 ++++++++++-
>  libavcodec/vaapi_vp8.c    |  8 +++++++-
>  libavcodec/vaapi_vp9.c    |  8 +++++++-
>  6 files changed, 55 insertions(+), 25 deletions(-)
> 
> diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
> index 69512e1d45..5fc9767802 100644
> --- a/libavcodec/vaapi_decode.c
> +++ b/libavcodec/vaapi_decode.c
> @@ -408,7 +408,8 @@ static const struct {
>  static int vaapi_decode_make_config(AVCodecContext *avctx,
>                                      AVBufferRef *device_ref,
>                                      VAConfigID *va_config,
> -                                    AVBufferRef *frames_ref)
> +                                    AVBufferRef *frames_ref,
> +                                    int dpb_size)
>  {
>      AVVAAPIHWConfig       *hwconfig    = NULL;
>      AVHWFramesConstraints *constraints = NULL;
> @@ -549,22 +550,8 @@ static int
> vaapi_decode_make_config(AVCodecContext *avctx,
>          if (err < 0)
>              goto fail;
> 
> -        frames->initial_pool_size = 1;
> -        // Add per-codec number of surfaces used for storing reference frames.
> -        switch (avctx->codec_id) {
> -        case AV_CODEC_ID_H264:
> -        case AV_CODEC_ID_HEVC:
> -            frames->initial_pool_size += 16;
> -            break;
> -        case AV_CODEC_ID_VP9:
> -            frames->initial_pool_size += 8;
> -            break;
> -        case AV_CODEC_ID_VP8:
> -            frames->initial_pool_size += 3;
> -            break;
> -        default:
> -            frames->initial_pool_size += 2;
> -        }
> +        if (dpb_size > 0)
> +            frames->initial_pool_size = dpb_size + 1;
>      }
> 
>      av_hwframe_constraints_free(&constraints);
> @@ -583,8 +570,9 @@ fail:
>      return err;
>  }
> 
> -int ff_vaapi_common_frame_params(AVCodecContext *avctx,
> -                                 AVBufferRef *hw_frames_ctx)
> +int ff_vaapi_frame_params_with_dpb_size(AVCodecContext *avctx,
> +                                        AVBufferRef *hw_frames_ctx,
> +                                        int dpb_size)
>  {
>      AVHWFramesContext *hw_frames = (AVHWFramesContext
> *)hw_frames_ctx->data;
>      AVHWDeviceContext *device_ctx = hw_frames->device_ctx;
> @@ -597,7 +585,7 @@ int
> ff_vaapi_common_frame_params(AVCodecContext *avctx,
>      hwctx = device_ctx->hwctx;
> 
>      err = vaapi_decode_make_config(avctx, hw_frames->device_ref,
> &va_config,
> -                                   hw_frames_ctx);
> +                                   hw_frames_ctx, dpb_size);
>      if (err)
>          return err;
> 
> @@ -607,6 +595,13 @@ int
> ff_vaapi_common_frame_params(AVCodecContext *avctx,
>      return 0;
>  }
> 
> +int ff_vaapi_common_frame_params(AVCodecContext *avctx,
> +                                 AVBufferRef *hw_frames_ctx)
> +{
> +    // Set common dpb_size for vc1/mjpeg/mpeg2/mpeg4.
> +    return ff_vaapi_frame_params_with_dpb_size(avctx, hw_frames_ctx, 2);
> +}
> +
>  int ff_vaapi_decode_init(AVCodecContext *avctx)
>  {
>      VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
> @@ -666,7 +661,9 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
>      ctx->hwctx  = ctx->device->hwctx;
> 
>      err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
> -                                   &ctx->va_config, avctx->hw_frames_ctx);
> +                                   &ctx->va_config, avctx->hw_frames_ctx,
> +                                   0);
> +
>      if (err)
>          goto fail;
> 
> diff --git a/libavcodec/vaapi_decode.h b/libavcodec/vaapi_decode.h
> index 6b415dd1d3..c3e74bf9c7 100644
> --- a/libavcodec/vaapi_decode.h
> +++ b/libavcodec/vaapi_decode.h
> @@ -98,6 +98,9 @@ int ff_vaapi_decode_cancel(AVCodecContext *avctx,
>  int ff_vaapi_decode_init(AVCodecContext *avctx);
>  int ff_vaapi_decode_uninit(AVCodecContext *avctx);
> 
> +int ff_vaapi_frame_params_with_dpb_size(AVCodecContext *avctx,
> +                                        AVBufferRef *hw_frames_ctx,
> +                                        int dpb_size);
>  int ff_vaapi_common_frame_params(AVCodecContext *avctx,
>                                   AVBufferRef *hw_frames_ctx);
> 
> diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
> index dd2a657160..8d7f5c2004 100644
> --- a/libavcodec/vaapi_h264.c
> +++ b/libavcodec/vaapi_h264.c
> @@ -385,6 +385,15 @@ static int vaapi_h264_decode_slice(AVCodecContext
> *avctx,
>      return 0;
>  }
> 
> +static int ff_vaapi_h264_frame_params(AVCodecContext *avctx,
> +                                   AVBufferRef *hw_frames_ctx)
> +{
> +    const H264Context *h = avctx->priv_data;
> +    const SPS       *sps = h->ps.sps;
> +    return ff_vaapi_frame_params_with_dpb_size(avctx, hw_frames_ctx,
> +                                               sps->ref_frame_count + sps-
> >num_reorder_frames);
> +}
> +
>  const AVHWAccel ff_h264_vaapi_hwaccel = {
>      .name                 = "h264_vaapi",
>      .type                 = AVMEDIA_TYPE_VIDEO,
> @@ -396,7 +405,7 @@ const AVHWAccel ff_h264_vaapi_hwaccel = {
>      .frame_priv_data_size = sizeof(VAAPIDecodePicture),
>      .init                 = &ff_vaapi_decode_init,
>      .uninit               = &ff_vaapi_decode_uninit,
> -    .frame_params         = &ff_vaapi_common_frame_params,
> +    .frame_params         = &ff_vaapi_h264_frame_params,
>      .priv_data_size       = sizeof(VAAPIDecodeContext),
>      .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
>  };
> diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
> index c69d63d8ec..41e973626c 100644
> --- a/libavcodec/vaapi_hevc.c
> +++ b/libavcodec/vaapi_hevc.c
> @@ -421,6 +421,15 @@ static int vaapi_hevc_decode_slice(AVCodecContext
> *avctx,
>      return 0;
>  }
> 
> +static int ff_vaapi_hevc_frame_params(AVCodecContext *avctx,
> +                                   AVBufferRef *hw_frames_ctx)
> +{
> +    const HEVCContext *s = avctx->priv_data;
> +    const HEVCSPS   *sps = s->ps.sps;
> +    return ff_vaapi_frame_params_with_dpb_size(avctx, hw_frames_ctx,
> +                                               sps->temporal_layer[sps->max_sub_layers -
> 1].max_dec_pic_buffering);
> +}
> +
>  const AVHWAccel ff_hevc_vaapi_hwaccel = {
>      .name                 = "hevc_vaapi",
>      .type                 = AVMEDIA_TYPE_VIDEO,
> @@ -432,7 +441,7 @@ const AVHWAccel ff_hevc_vaapi_hwaccel = {
>      .frame_priv_data_size = sizeof(VAAPIDecodePictureHEVC),
>      .init                 = ff_vaapi_decode_init,
>      .uninit               = ff_vaapi_decode_uninit,
> -    .frame_params         = ff_vaapi_common_frame_params,
> +    .frame_params         = ff_vaapi_hevc_frame_params,
>      .priv_data_size       = sizeof(VAAPIDecodeContext),
>      .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
>  };
> diff --git a/libavcodec/vaapi_vp8.c b/libavcodec/vaapi_vp8.c
> index 2426b30f13..4b74b9e0ad 100644
> --- a/libavcodec/vaapi_vp8.c
> +++ b/libavcodec/vaapi_vp8.c
> @@ -220,6 +220,12 @@ fail:
>      return err;
>  }
> 
> +static int ff_vaapi_vp8_frame_params(AVCodecContext *avctx,
> +                                  AVBufferRef *hw_frames_ctx)
> +{
> +    return ff_vaapi_frame_params_with_dpb_size(avctx, hw_frames_ctx, 3);
> +}
> +
>  const AVHWAccel ff_vp8_vaapi_hwaccel = {
>      .name                 = "vp8_vaapi",
>      .type                 = AVMEDIA_TYPE_VIDEO,
> @@ -231,7 +237,7 @@ const AVHWAccel ff_vp8_vaapi_hwaccel = {
>      .frame_priv_data_size = sizeof(VAAPIDecodePicture),
>      .init                 = &ff_vaapi_decode_init,
>      .uninit               = &ff_vaapi_decode_uninit,
> -    .frame_params         = &ff_vaapi_common_frame_params,
> +    .frame_params         = &ff_vaapi_vp8_frame_params,
>      .priv_data_size       = sizeof(VAAPIDecodeContext),
>      .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
>  };
> diff --git a/libavcodec/vaapi_vp9.c b/libavcodec/vaapi_vp9.c
> index f384ba7873..ce15701405 100644
> --- a/libavcodec/vaapi_vp9.c
> +++ b/libavcodec/vaapi_vp9.c
> @@ -168,6 +168,12 @@ static int vaapi_vp9_decode_slice(AVCodecContext
> *avctx,
>      return 0;
>  }
> 
> +static int ff_vaapi_vp9_frame_params(AVCodecContext *avctx,
> +                                  AVBufferRef *hw_frames_ctx)
> +{
> +    return ff_vaapi_frame_params_with_dpb_size(avctx, hw_frames_ctx, 8);
> +}
> +
>  const AVHWAccel ff_vp9_vaapi_hwaccel = {
>      .name                 = "vp9_vaapi",
>      .type                 = AVMEDIA_TYPE_VIDEO,
> @@ -179,7 +185,7 @@ const AVHWAccel ff_vp9_vaapi_hwaccel = {
>      .frame_priv_data_size = sizeof(VAAPIDecodePicture),
>      .init                 = ff_vaapi_decode_init,
>      .uninit               = ff_vaapi_decode_uninit,
> -    .frame_params         = ff_vaapi_common_frame_params,
> +    .frame_params         = ff_vaapi_vp9_frame_params,
>      .priv_data_size       = sizeof(VAAPIDecodeContext),
>      .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
>  };
> --
> 2.17.1

Ping?

 - linjie


More information about the ffmpeg-devel mailing list