Opened 7 weeks ago

Last modified 6 weeks ago

#11292 open defect

AMD Hardware Encoding is Broken in versions >= 7.1

Reported by: TanMan Owned by:
Priority: important Component: avcodec
Version: git-master Keywords:
Cc: primeadvice@gmail.com Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Using HEVC_AMF encoder on Ryzen 5700G on versions >= 7.1 results in huge files:
How to reproduce:

% ffmpeg -i input -c:v hevc_amf -quality 5 output
ffmpeg version 7.1
also tested with version 2024-11-06-git-4047b887fc-full_build-www.gyan.dev
running on Windows 11 23H2 22631.4391

Output under >= 7.1 generates this error:
[hevc_amf @ 000002ef6f027500] rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set
I am unable to find anywhere to set this rc_max_rate, and the resulting file has a much higher bitrate than the original x264 source and is huge.
This worked fine in previous versions (through 7.01) and resulted in very good quality 1080p video at 2kbps and encoded files very fast (6x to 12x).
The libx265 encoder still works fine in >= 7.1. The resulting 1080p files run about 1.5kbps and look fine, but it takes 3 to 6 times longer (2x to 3x).

Change History (12)

comment:1 by Gyan, 7 weeks ago

Cc: primeadvice@gmail.com added
Component: ffmpegavcodec
Priority: normalimportant
Status: newopen

In June 2024, a change* was made which made Peak VBR the fallback rate control method, without checking if the max rate had been set.

*see 02430680b02ee42472148e67e178b6d1c2ac43fd

comment:2 by Gyan, 7 weeks ago

Meanwhile, you can set -maxrate to set rc_max_rate.

comment:3 by TanMan, 7 weeks ago

I had tried -maxrate, but it didn't help. Since you recommended it, I tried it again:

ffmpeg -i input -c:v hevc_amf -maxrate 2000k output

The error message is indeed gone, but the maxrate is not being honored. This is why I thought it wasn't right, and I didn't include this in my original posting. This is the encoding status being reported while encoding:

bitrate=20136.7kbits/s speed=14.2x

So it's fast, and there's no error, but it's still creating a huge file.

Last edited 7 weeks ago by TanMan (previous) (diff)

comment:4 by nyanmisaka, 7 weeks ago

AMD has differentiated drivers for Vega/Polaris and RDNA since late 2023. So when adding features to ffmpeg for the new drivers, limitations in the old drivers can be ignored. Maybe also report this in the AMF repo.

https://github.com/GPUOpen-LibrariesAndSDKs/AMF/issues

Last edited 7 weeks ago by nyanmisaka (previous) (diff)

comment:6 by Roman, 7 weeks ago

  1. The correct command line is expect to be:

ffmpeg.exe -i input.mp4 -c:v h264_amf -b:v 1M -max_rate 1.6M out.mp4

  1. If the command line is without -max_rate, then there is a warning message “rate control mode is PEAK_CONSTRAINED_VBR, but rc_max_rate is not set”. The encoding will still work normally, and the default max_rate of 1.5x (1.5 * bitrate) will be applied.

ffmpeg.exe -i input.mp4 -c:v h264_amf -b:v 1M out.mp4

  1. If the command line is without -b:v 1M, then a default bitrate of 20Mbps will be applied.

ffmpeg.exe -i input.mp4 -c:v h264_amf out.mp4

  1. Considering the reported case plus -maxrate,

ffmpeg -i input -c:v hevc_amf -maxrate 2000k output

Since the command line does not specify the bitrate -b:v, then the default bitrate of 20M will be applied by AMF.
Since the -maxrate 2000k is smaller than the default bitrate of 20M, then the -maxrate 2000k will be ignored and won’t take effect.
As a result, a large file will be produced where the actual bitrate is 20M.

A patch will be submitted to remove the warning message “rate control mode is PEAK_CONSTRAINED_VBR, but rc_max_rate is not set”. It brought a little confusion.

For the bitrate parameter -b:v, we previously set it to 2M in FFmpeg, but it has now been changed to -1. In AMF, the default value is 20M. This explains the difference seen between past and present behavior.

comment:7 by Gyan, 7 weeks ago

A default of 20M is excessively high. The lavc wrapper should set it adaptatively i.e. a function of W x H x fps.

comment:8 by TanMan, 7 weeks ago

@Roman, thank you so much for the great explanation. In particular, the need to set the video bitrate (-b:v) and how the -maxrate is calculated when not specified (1.5x). Using your new information, I reencoded the target video using:

ffmpeg -i input -c:v hevc_amf -b:v 1M output

This encoding resulted in a reasonable bitrate of 1651bps which looks fine. The 2:08:48 1920x800 movie I encoded is now a reasonable 1.5GB, and that includes 590MB for the DD 5.1 audio. And yes, it threw the rc_max_rate error since I didn't set -maxrate.

Now that I have properly thanked you for fixing my issue, I have 3 additional comments:

  1. The change in the amf encoder defaults is not documented in the changelog. Something major like this needs to be highlighted in something other than a github diff list.
  1. This change eliminates the parity with the libx265 encoder. libx265 appears to still use a lower default bitrate - the encode of this same movie using libx265 (CPU only) was much, much slower, but resulted in a tiny file (under 1GB) and a bitrate under 1kbps.
  1. I agree with @Gyan that 20M is excessive for x265. There seems to be no reason for this change as x265 gives great results with much lower bitrates.

comment:9 by TanMan, 7 weeks ago

Just one update in case someone is reading this. I had to increase the bitrate since some of the more complex scenes were blocky. I'm now using:

ffmpeg -i input -c:v hevc_amf -b:v 1.5M -maxrate 2M output

comment:10 by Roman, 6 weeks ago

The default target bitrate value for each encoder is specified and documented in each corresponding API doc, for example in H264:
https://github.com/GPUOpen-LibrariesAndSDKs/AMF/blob/master/amf/doc/AMF_Video_Encode_API.md?plain=1#L1026

Thank you for the suggestion of getting a reasonable bitrate based on the W x H, or additionally taking the framerate into account. It is a good suggestion and will be planned in AMF later.

comment:11 by TanMan, 6 weeks ago

I'm sorry. I should have been more clear that my documentation suggestion was for ffmpeg, not for the AMF Encoder API. I did not mean to imply that this change was not documented, it's just that it's not documented in ffmpeg. In particular, this page needs to be updated, and not being an expert, I don't think I should do it:

https://trac.ffmpeg.org/wiki/Hardware/AMF

With that said, the link you provided was for line 1026 of a 2750 line document for one of the API's USED by ffmpeg and not ffmpeg itself. This is pretty much the definition of something being buried. I'm not sure how someone like me, an old systems programmer who uses ffmpeg to encode video in a script I wrote, and who is a user of the AMF encoder through ffmpeg, would be expected to find this document, let alone the line in the middle of said document.

So thank you for pointing out the documentation of the AMF Encoder API, and I will review this document thoroughly, but this is not sufficient for ffmpeg's documentation.

Version 0, edited 6 weeks ago by TanMan (next)

comment:12 by Roman, 6 weeks ago

There is an open patch to add HW context info FFmpeg.

https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=2553

Once this is approved and merged in, then we can update the docs.

Note: See TracTickets for help on using tickets.