Opened 3 years ago

Last modified 3 months ago

#10417 new defect

yadif_cuda: Input frame is not the in the configured hwframe context.

Reported by: ronag Owned by:
Priority: normal Component: avfilter
Version: 6.0 Keywords: cuda filter
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

The following will fail:

ffmpeg -i http://172.18.0.1:8000/file/8eb02e2a2e42e658.mov -filter:v 'format=yuv444p,hwupload_cuda,yadif_cuda=mode=send_field:parity=auto:deint=interlaced,scale_cuda=1920:-1,hwdownload,format=yuv444p' -f mp4 /tmp/asd.mp4 -y
[hwdownload @ 0x55cd0a1a8000] [error] Input frame is not the in the configured hwframe context.
[error] Error while filtering: Invalid argument
[error] Failed to inject frame into filter network: Invalid argument
[fatal] Error while processing the decoded data for stream #0:1

If I add a "scale_cuda" filter after "yadif_cuda" then it will work:

ffmpeg -i http://172.18.0.1:8000/file/8eb02e2a2e42e658.mov -filter:v 'format=yuv444p,hwupload_cuda,yadif_cuda=mode=send_field:parity=auto:deint=interlaced,scale_cuda=1920:-1,hwdownload,format=yuv444p' -f mp4 /tmp/asd.mp4 -y

Change History (3)

comment:1 by ronag, 3 years ago

I have seen similar issues with transpose_npp.

comment:2 by Thomas Maxwell, 3 months ago

The issue happens if yadif_cuda tries to pass through a frame to the output without processing.

You can reproduce the issue by using a progressive video input and a filter:

ffmpeg -i ../ESPNHD_1m.ts -filter:v 'format=yuv420p,hwupload_cuda,yadif_cuda=deint=1,hwdownload' ./ESPNHD_1m_tx_gpu2.ts -y

It fails:

[hwdownload @ 0x7ff094003b80] Input frame is not the in the configured hwframe context.

If you change the mode to "deint=0" to process all frames, we have no issues.

I think the issue is that hwupload_cuda and yadif_cuda both have their own hwframes context created in the output link initialization time:

static int cudaupload_config_output(AVFilterLink *outlink)
{
...
    s->hwframe = av_hwframe_ctx_alloc(s->hwdevice);

and

static int config_output(AVFilterLink *link)
{
...
    link->hw_frames_ctx = av_hwframe_ctx_alloc(s->device_ref);

In case of processing a frame the output frame of the yadif filter will be in its own output hw frame context, while in case of passing through it will stay in the hwupload_cuda one.

A developer can confirm the issue.

Note: Adding "scale_cuda" won't help if its output is the same size as its input so it also passes through the frame.

Note2: I tried to replicate the same with scale_cuda but it works because it uses the input hw frames context in case of passthrough

ffmpeg -i ../ESPNHD_1m.ts -filter:v 'format=yuv420p,hwupload_cuda,scale_cuda=w=1280:h=720:passthrough=1,hwdownload' ./ESPNHD_1m_tx_gpu2.ts -y
    if (s->passthrough && in_width == out_width && in_height == out_height && in_format == out_format) {
        s->frames_ctx = av_buffer_ref(ctx->inputs[0]->hw_frames_ctx);

comment:3 by Thomas Maxwell, 3 months ago

The workaround is to add "scale_cuda" with "passthrough=0" so all frames will be processed.
"scale_cuda" filter is not that strict as the "hwdownload" one about the hardware context of its input frames. (whether it is the same as in the input link or not)

Note: See TracTickets for help on using tickets.