[FFmpeg-devel] [PATCH 2/2] lavc/vp9: support hardware decode with resolution changing on inter frame

Hendrik Leppkes h.leppkes at gmail.com
Fri Dec 27 12:22:09 EET 2019


On Fri, Dec 27, 2019 at 9:59 AM Linjie Fu <linjie.fu at intel.com> wrote:
>
> VP9 decoder should be able to handle resolution changing on inter
> frame without re-initialization. For hardware decoder, re-allocate hardware
> frame surface.
>
> Fix #8068 for VA-API.
>
> Signed-off-by: Linjie Fu <linjie.fu at intel.com>
> ---
> Request for comments.
> This works for VA-API, however for dxva2 it didn't cover all cases.
>
> Another idea is to register a call-back function in AVHWAccel (such as
> ff_vp9_dxva2_hwaccel) to handle surface re-allocation according to
> the hardware decoder.
>
>  libavcodec/vp9.c | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
> index 0fd15ef..a7b4c6a 100644
> --- a/libavcodec/vp9.c
> +++ b/libavcodec/vp9.c
> @@ -34,6 +34,7 @@
>  #include "vp9dec.h"
>  #include "libavutil/avassert.h"
>  #include "libavutil/pixdesc.h"
> +#include "decode.h"
>
>  #define VP9_SYNCCODE 0x498342
>
> @@ -220,11 +221,20 @@ static int update_size(AVCodecContext *avctx, int w, int h)
>          *fmtp++ = s->pix_fmt;
>          *fmtp = AV_PIX_FMT_NONE;
>
> -        ret = ff_thread_get_format(avctx, pix_fmts);
> -        if (ret < 0)
> -            return ret;
> +        if (avctx->internal->hwaccel_priv_data && s->pix_fmt == s->gf_fmt && (s->w != w || s->h != h)) {
> +            const AVHWDeviceContext *device_ctx =
> +                (AVHWDeviceContext*)avctx->hw_device_ctx->data;
> +            ret = ff_decode_get_hw_frames_ctx(avctx, device_ctx->type);
> +            if (ret < 0)
> +                return ret;
> +        } else {
> +            ret = ff_thread_get_format(avctx, pix_fmts);
> +            if (ret < 0)
> +                return ret;
> +
> +            avctx->pix_fmt = ret;
> +        }
>
> -        avctx->pix_fmt = ret;
>          s->gf_fmt  = s->pix_fmt;
>          s->w = w;
>          s->h = h;

hwaccels are not guaranteed to have a hw_frames ctx, and avcodec is
not guaranteed to manage the surfaces it decodes to at all (they could
be shared with eg. a renderer and allocated externally), as such a
decoder really can't reliably re-allocate this itself - thats what the
get_format callback is for, which informs the user that new dimensions
are required.

- Hendrik


More information about the ffmpeg-devel mailing list