Opened 5 months ago

Last modified 3 months ago

#10735 new defect

Bug: FFmpeg's qsv encoder wrappers broken with the -g parameter set, cannot enforce set keyframe interval

Reported by: Dennis E. Mungai Owned by:
Priority: critical Component: avcodec
Version: git-master Keywords: quicksync
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description (last modified by Dennis E. Mungai)

Summary of the bug:

Any invocation of the h264_qsv encoder with a set GOP size via the -g option results with the specified GOP size(s) not being respected.

Sample command:

The trivial example below demonstrates this anomaly with h264_qsv:

ffmpeg -thread_queue_size 5120 -nostdin -y -fflags +genpts -y \
-init_hw_device vaapi=va:/dev/dri/renderD129 \
-init_hw_device qsv=qs@va \
-filter_hw_device qs \
-extra_hw_frames 64 \
-threads:v 2 -async 1 \
-probesize 10M -analyzeduration 10M \
-f mpegts -fix_teletext_pts 1 -scan_all_pmts 1 -merge_pmt_versions 1 \
-i "input.ts" \
-vf 'hwmap=derive_device=qsv,format=qsv,vpp_qsv=deinterlace=2:scale_mode=0:async_depth=4' \
-sc_threshold 0 -strict -1 -bitrate_limit:v 0 -g:v 50 -async_depth:v 4 -look_ahead_depth:v 40 \
-preset:v medium -refs:v 5 -extbrc:v 1 -bf:v 0 -low_power:v 1 -r:v 25 \
-b:v 4500k -minrate:v 4500k -maxrate:v 4500k -bufsize:v 9000k -rc_init_occupancy:v 4500k -c:v h264_qsv \
-c:a aac -ac 2 -b:a 128k \
-flags -global_header+cgop -max_muxing_queue_size 2048 -max_interleave_delta 0 -flush_packets 0 -fps_mode cfr -f mpegts \
-y "out.ts"

This was verified with ffprobe as shown:

ffprobe -select_streams v -show_entries frame=pict_type,pts_time -of csv=p=0 -skip_frame nokey -i filter.ts > Iframes.txt

Which showed an abnormal GOP size of 10 being set as per sample with -async_depth 4 set, which is the default:

less Iframes.txt
2.981333,I
13.221333,I
23.461333,I
33.701333,I
43.941333,I
54.181333,I
64.421333,I
74.661333,I
84.901333,I
95.141333,I
105.381333,I
115.621333,I
125.861333,I
136.101333,I
146.341333,I
156.581333,I
166.821333,I

The sample encode from ffmpeg showing the bug above is attached.

Also tested on ffmpeg 6.1, same issue. Ticket edited to reflect this.

Attachments (1)

outputaa (2.3 MB ) - added by Dennis E. Mungai 5 months ago.
The sample output

Change History (5)

by Dennis E. Mungai, 5 months ago

Attachment: outputaa added

The sample output

comment:1 by Dennis E. Mungai, 5 months ago

Description: modified (diff)

comment:2 by Dennis E. Mungai, 5 months ago

Description: modified (diff)
Summary: FFmpeg 6.1 qsv encoder wrappers broken with the -g parameter set, cannot enforce set keyframe intervalBug: FFmpeg's qsv encoder wrappers broken with the -g parameter set, cannot enforce set keyframe interval with the default async_depth setting
Version: 6.0git-master

comment:3 by Dennis E. Mungai, 5 months ago

Description: modified (diff)
Summary: Bug: FFmpeg's qsv encoder wrappers broken with the -g parameter set, cannot enforce set keyframe interval with the default async_depth settingBug: FFmpeg's qsv encoder wrappers broken with the -g parameter set, cannot enforce set keyframe interval

comment:4 by wenbin,chen, 3 months ago

I cannot run the command you provide, so I make some changes to make it work

ffmpeg -thread_queue_size 5120 -nostdin -y -fflags +genpts -y \
-init_hw_device vaapi=va:/dev/dri/renderD129 \
-init_hw_device qsv=qs@va \
-filter_hw_device qs \
-extra_hw_frames 64 \
-threads:v 2 -async 1 \
-probesize 10M -analyzeduration 10M \
-hwaccel vaapi -hwaccel_output_format vaapi \
-f mpegts -fix_teletext_pts 1 -scan_all_pmts 1 -merge_pmt_versions 1 \
-i "input.ts" \
-vf 'hwmap=derive_device=qsv,format=qsv,vpp_qsv=deinterlace=2:scale_mode=0:async_depth=4' \
-sc_threshold 0 -strict -1 -bitrate_limit:v 0 -g:v 50 -async_depth:v 4 -look_ahead_depth:v 40 \
-preset:v medium -refs:v 5 -extbrc:v 1 -bf:v 0 -low_power:v 1 -r:v 25 \
-b:v 4500k -minrate:v 4500k -maxrate:v 4500k -bufsize:v 9000k -rc_init_occupancy:v 4500k -c:v h264_qsv \
-c:a aac -ac 2 -b:a 128k \
-flags -global_header+cgop -max_muxing_queue_size 2048 -max_interleave_delta 0 -flush_packets 0 -fps_mode cfr -f mpegts \
-y "out.ts"

I added "-hwaccel vaapi -hwaccel_output_format vaapi" options

gop_size(-g) is measured by number of frames not by pts time. You should count frames between two I frames to verify it.

I see you enabled extbrc. It will automatically enable adaptive_i which makes the result doesn't strictly obey the gop_size you set. It inserts I frame when it is needed, for example when scene change.

Note: See TracTickets for help on using tickets.