Opened 3 years ago

Last modified 10 months ago

#10608 new defect

AV1 decoder gets "Static surface pool size exceeded" issue with "-hwaccel d3d11va"

Reported by: Evgeny Owned by:
Priority: normal Component: avcodec
Version: git-master Keywords: av1 d3d11va av1_amf
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
When we use d3d11 hardware decoder with av1_amf encoder, the input stream is av1 format, and specify parameter hwaccel_output_format parameter, there are errors “"Static surface pool size exceeded.”

[AVHWFramesContext @ 00000166637640c0] Static surface pool size exceeded.
[av1 @ 0000016663763a00] get_buffer() failed
[av1 @ 0000016663763a00] thread_get_buffer() failed
[av1 @ 0000016663763a00] Failed to allocate space for current frame.
[av1 @ 0000016663763a00] Get current frame error
[vist#0:0/av1 @ 0000016663328740] Error submitting packet to decoder: Cannot allocate memory

This error happens only when the source is av1 format and specify -hwaccel_output_format d3d11. I tested it on nvidia machine, there are similar errors.

How to reproduce:

ffmpeg -hwaccel d3d11va -hwaccel_output_format d3d11 -i av1.mp4 -c:v av1_amf out.mp4
ffmpeg master
built on Windows with msys2

Change History (3)

comment:1 by SuRGeoNix, 11 months ago

It seems that the initial_pool_size of the hardware frames must be + 1 (or even more? in my case -nvidia ffmpeg v7.1- works) for AV1. Probably related code https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/dxva2.c#L623

/* 1 base work surface */
num_surfaces = 1;

/* add surfaces based on number of possible refs */
if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC)
        num_surfaces += 16;
else if (avctx->codec_id == AV_CODEC_ID_VP9 || avctx->codec_id == AV_CODEC_ID_AV1)
        num_surfaces += 8;
else
        num_surfaces += 2;

Maybe it just requires more margin (eg +12 surfaces for safety?)

However, I see that a +1 and +3 margin already added
https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/decode.c#L1082C39-L1082C43

ret = avcodec_get_hw_frames_parameters(avctx,
   avctx->hw_device_ctx,
   avctx->hwaccel->pix_fmt,
   &avctx->hw_frames_ctx);
if (ret < 0)
        return ret;

frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;


if (frames_ctx->initial_pool_size) {
        // We guarantee 4 base work surfaces. The function above guarantees 1
        // (the absolute minimum), so add the missing count.
        frames_ctx->initial_pool_size += 3;
}

But the error I got
"Consider setting extra_hw_frames to a larger value (currently set to 4, giving a pool size of 13)."

looks like it sets the pool size to 9 (13 -4 my extra frames) and it doesn't add the other 3 from decode.c?

Last edited 11 months ago by SuRGeoNix (previous) (diff)

comment:2 by SuRGeoNix, 10 months ago

As this is not happening with any AV1 file, I provide a sample:

https://drive.google.com/file/d/17v59r7FQiojE6DZHjCZHXS3ePZryKQbq/view?usp=sharing

comment:3 by SuRGeoNix, 10 months ago

My apologies, it was my mistake by missing one extra frame that I needed in some cases.

Note: See TracTickets for help on using tickets.