[Bug]: QVBR/HQVBR, quality and rate options seem ignored
Describe the bug
Setting bitrate options or even -qvbr_quality_level 51 (the worst possible quality) seems completely ignored.
To Reproduce This is the ffmpeg git build!
LD_LIBRARY_PATH=/home/mark/pkgbuilds/ffmpeg/upstream/build/lib \
./ffmpeg -hwaccel amf -hwaccel_device /dev/dri/renderD128 -init_hw_device amf=/dev/dri/renderD128 \
-y -i ~/Videos/eso1706c.avi \
-c:v hevc_amf \
-usage high_quality \
-rc qvbr \
-qvbr_quality_level 51 \
-minrate 1M \
-maxrate 10M \
-quality quality \
-preset quality \
-profile:v main10 \
-profile_tier high \
-preanalysis 1 -enforce_hrd 1 -filler_data 1 \
-pix_fmt nv12 \
-b:v 5M \
-f matroska test.mkv
The video i'm trying this on (warning 2GB, 4k)!: https://cdn.eso.org/videos/ultra_hd_broadcast/eso1706c.avi
Setup (please complete the following information):
- OS: Linux
- Driver Version: Current Git of this repo
- GPU: 7900 XT
- Which component has the issue: Encoder
- Using ffmpeg Git (no custom patches)
Debug Log (please upload or paste): No errors or warnings
Expected behavior A clear and concise description of what you expected to happen.
Screenshots N/A
Additional context
I tried various options to force bitrates. The -enforce_hrd 1 -filler_data 1 comes from another hint in another bug, it seems to not help at all.
Also, as an aside. Try the encoding line! Then look at the result. The video jumps back and forth! As this is a planetary illustration, it's easier to explain :) The planets jump back and forth in their orbit. That's not in the source! And that's not the case if you'd encode it with, say, vbr_peak. The rate issue is the one i'm reporting here but there is another issue hidden in this too.
We tried your video clip and found that "-qvbr_quality_level 51" produces highest quality and "-qvbr_quality_level 1" produces lowest quality. If you see the issue (no effect), please provide output clips to compare and the method you compare them.
Hi Mikhail,
That level is confusing. In other encoder settings higher is often worse not better. For example a crf of 51 is as bad as you can get while a crf of 1 is essentially lossless.
Anyhow, i uploaded two files here: https://limewire.com/d/1fce0ed7-de45-4597-829c-afd1840f5da4#SBJk45nsWOC6LdglDKOmqHhlwwT8Q2LvdOemixi2XKQ
-
test_qvbr_1.mkvwith-qvbr_quality_level 1 -
test_qvbr_51.mkvwith-qvbr_quality_level 51
The command is otherwise exactly the same as provided in my first post.
Observations:
-
test_qvbr_1.mkvis bigger (143MB vs 138MB fortest_qvbr_51.mkv) which makes no sense if 1 is bad and 51 is great quality - Neither follows the bitrate limitations
While encoding, both did say:
Stream #0:0: Video: hevc, nv12(tv, progressive), 3840x2160, q=2-31, 5000 kb/s, 25 fps, 1k tbn
Metadata:
encoder : Lavc61.33.102 hevc_amf
[hevc_amf @ 0x5714996cd900] Data acquired but delayed SubmitInput returned AMF_INPUT_FULL- should not happen
Emphasis on the 5000 kb/s which isn't what i'm seeing in the resulting video (it would've been around 1MB if it had followed the bitrate limits).
I am playing the video with mpv (and ffplay). Both videos that i uploaded show the jumping effect too.
I debugged the bitrate part of the issue a little, it's puzzling.
I'm trying it with qvbr and vbr_peak (explicitly trying vbr_peak because it seems to follow contraints). Note that with vbr_peak i also disable preanalysis.
I do see the bitrate settings being applied in both modes into AMF. The relevant logging:
0125-01-20 17:06:31 A11FB6C0 [AMFEncoderCoreHevc] Debug: SetProperty TL0.QL0.HevcPeakBitrate:10000000
[AVHWDeviceContext @ 0x75008d7e9300] AMFEncoderCoreHevc: 0125-01-20 17:06:31 A11FB6C0 [AMFEncoderCoreHevc] Debug: SetProperty TL0.QL0.HevcPeakBitrate:10000000
0125-01-20 17:06:31 A11FB6C0 [AMFEncoderCoreHevc] Debug: SetProperty TL0.QL0.HevcTargetBitrate:5000000
[AVHWDeviceContext @ 0x75008d7e9300] AMFEncoderCoreHevc: 0125-01-20 17:06:31 A11FB6C0 [AMFEncoderCoreHevc] Debug: SetProperty TL0.QL0.HevcTargetBitrate:5000000
0125-01-20 17:06:31 A11FB6C0 [AMFEncoderCoreHevc] Debug: SetProperty TL0.QL0.HevcVBVBufferSize:5000000
[AVHWDeviceContext @ 0x75008d7e9300] AMFEncoderCoreHevc: 0125-01-20 17:06:31 A11FB6C0 [AMFEncoderCoreHevc] Debug: SetProperty TL0.QL0.HevcVBVBufferSize:5000000
Which leads me to think that the bitrate is set in both modes but something somewhere nullifies that setting with qvbr?...
Hello @markg85 just another AMF user on the internet but I believe your uncontrollable bitrate issue stems from the AMF_VIDEO_ENCODER_PREENCODE_ENABLED setting that is set to True when using USAGE HIGH-QUALITY paired with any of the High Quality rate control methods (HQCBR, HQVBR and in your case QVBR.)
When AMF_VIDEO_ENCODER_PREENCODE_ENABLED is set to true for me in OBS with HQCBR the bitrate becomes uncontrollable even with FillerData and HRD set to true. So I would suggest using USAGE TRANSCODE instead to have AMF_VIDEO_ENCODER_PREENCODE_ENABLED set to False by default.
The HQ rate control methods and AMF_VIDEO_ENCODER_PREENCODE_ENABLED pairing have been a problem for a while but I hope this helps and maybe the AMF team can confirm or repro this issue.
Hi @Sinfull-snake! Thank you for your hints, that's much appreciated!
My case here is slightly different then OBS usage (i assume you use it for streaming?). For streaming VBR_PEAK seems to be awesome.
My case here in this issue is archive encoding. I know the results x265 can get but it's slow. So i'm now trying to approach those results on AMF as close as i can in terms of quality while remaining within the ballpark size of x265. QVBR probably isn't even the one i need here, based on the docs i think HQVBR is probably best but that just gives the same problem as reported.
In my case that 5Mbit is nonsense but it serves the purpose of demonstrating a bug.
- Please refer to "https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/Rate%20Control%20Methods" for the explanation of of how AMF QVBR mode works - In QVBR mode, the file size is purely decided by the set quality level and the complexity of the video. In other word, any bitrate related values set by users will be ignored in QVBR mode.
- AMF QVBR mode follows the common sense that the higher the quality level, the better the quality. This is different from CRF of x264/5.
- The provided test video "https://cdn.eso.org/videos/ultra_hd_h265/eso1706c.mp4", is not the same as the one you used in your command line, "eso1706c.avi". If you could provide a link to that video, I can repeat your test to verify your result of Level 1 and Level 51.
Let me know and I am happy to help.
Hi @Feng-AMD
Interesting, i must have copied the wrong link.
Here is the correct link: https://cdn.eso.org/videos/ultra_hd_broadcast/eso1706c.avi and if that doesn't work as direct link, then go to it's page (here) and download the "4K Ultra HD Broadcast" one.
For clarity, the ffprobe on my local file:
❯ ffprobe ~/Videos/eso1706c.avi
ffprobe version n7.1 Copyright (c) 2007-2024 the FFmpeg developers
built with gcc 14.2.1 (GCC) 20240910
configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-frei0r --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libdav1d --enable-libdrm --enable-libdvdnav --enable-libdvdread --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgsm --enable-libharfbuzz --enable-libiec61883 --enable-libjack --enable-libjxl --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libplacebo --enable-libpulse --enable-librav1e --enable-librsvg --enable-librubberband --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpl --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-nvdec --enable-nvenc --enable-opencl --enable-opengl --enable-shared --enable-vapoursynth --enable-version3 --enable-vulkan
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.100 / 61. 19.100
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
Input #0, avi, from '/home/mark/Videos/eso1706c.avi':
Metadata:
date : 2017-02-16T13:00:48.0036
software : Adobe After Effects CC 2017 (Windows)
Duration: 00:00:26.24, start: 0.000000, bitrate: 648060 kb/s
Stream #0:0: Video: hqx (CHQX / 0x58514843), yuv422p16le(10 bpc), 3840x2160, 649039 kb/s, 25 fps, 25 tbr, 25 tbn
And on that file i linked to:
❯ ffprobe https://cdn.eso.org/videos/ultra_hd_broadcast/eso1706c.avi
ffprobe version n7.1 Copyright (c) 2007-2024 the FFmpeg developers
built with gcc 14.2.1 (GCC) 20240910
configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-frei0r --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libdav1d --enable-libdrm --enable-libdvdnav --enable-libdvdread --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgsm --enable-libharfbuzz --enable-libiec61883 --enable-libjack --enable-libjxl --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libplacebo --enable-libpulse --enable-librav1e --enable-librsvg --enable-librubberband --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpl --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-nvdec --enable-nvenc --enable-opencl --enable-opengl --enable-shared --enable-vapoursynth --enable-version3 --enable-vulkan
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.100 / 61. 19.100
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
Input #0, avi, from 'https://cdn.eso.org/videos/ultra_hd_broadcast/eso1706c.avi':
Metadata:
date : 2017-02-16T13:00:48.0036
software : Adobe After Effects CC 2017 (Windows)
Duration: 00:00:26.24, start: 0.000000, bitrate: 648060 kb/s
Stream #0:0: Video: hqx (CHQX / 0x58514843), yuv422p16le(10 bpc), 3840x2160, 649039 kb/s, 25 fps, 25 tbr, 25 tbn
Thank you for pointing out that wiki page, that's very helpful! QVBR might indeed be the wrong testcase for me. But HQVBR does seem to be the proper one, as it's described as:
HQ-VBR aims at improving perceptual quality by producing the constant perceptual quality close to target bitrate. To guarantee the minimum perceptual quality, and to avoid wasting bit budget, the bitrate accuracy at extremely low/high target bitrate will be reduced.
I just tested that statement and i can, sadly, confirm that the bitrate is not adhered to in HQVBR either. The command is exactly the same as my initial command here only qvbr replaced with hqvbr.
Note that the wiki states (for HQVBR: its peak bitrate is constrained by PEAK_BITRATE).
Also note that my command includes a -maxrate 10M
Which in the ffmpeg amf codebase is, probably, is used:
if (avctx->rc_max_rate) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE, avctx->rc_max_rate);
} else if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
av_log(ctx, AV_LOG_DEBUG, "rate control mode is vbr_peak but max_rate is not set, default max_rate will be applied.\n");
}
I say probably because i reverted to ffmpeg master which has amf logging disabled. It would crash in these modes where preanalysis is enabled, which is in hqvbr. So my verifying abilities are a bit reduced here.
As stated in the document "https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/Rate%20Control%20Methods", in HQVBR mode, "To guarantee the minimum perceptual quality, and to avoid wasting bit budget, the bitrate accuracy at extremely low/high target bitrate will be reduced."
In 4k video encoding, bitrate of 5Mbps is just too low to have a decent quality. That is why you can't get the target bitrate as you expect if rc is HQVBR.
If your app is sensitive to bitrate accuracy, I suggest that you choose PCVBR.
@Feng-AMD Could you be so kind to explain that?
The docs make you think that it's output can be controlled in terms of bitrate. If that isn't the case then it would be beyond super helpful to update the docs to reflect reality.
I also tried using 20Mbit, that is enough for 4k, still it AMF just seems to ignore it and shoot for around 40-60Mbit.
What use is there for QVBR and HQVBR at all if you can't steer it's output size in a certain direction. It certainly isn't good for archiving as AMF simply, objectively, isn't as good as x265 (it's advantage is speed, not quality). With x265 you would get both a higher quality and a much smaller size downside is that the encoding takes a few days...
Also, PCVBR doesn't exist in ffmpeg. Do you have a patch for me to try?
- qvbr and hqvbr provide users extra options of balancing bitrate and quality, with emphasis on perceptual quality.
- If users want rc with high bitrate accuracy, there is another option of PCVBR, or "peak constraint VBR", by setting "-rc vbr_peak". Please refer to "https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/AMF%20Encoder%20Settings%20and%20Tuning%20in%20FFmpeg" for more options.
- Please share your 20Mbit bitstream, and your command line to generate this bitstream so I can help to debug what went wrong. In my local testing I did not see that.
- We will review the document to highlight the differences among different rc modes in future updates.
qvbr and hqvbr provide users extra options of balancing bitrate and quality, with emphasis on perceptual quality.
I'm sorry but this is just saying nothing while saying something... What are those "extra options"? Do they work? Where are they? How do i use them? That "options of balancing bitrate" yet again implies you can control it, yet you can't. Or it's broken.
If users want rc with high bitrate accuracy, there is another option of PCVBR, or "peak constraint VBR", by setting "-rc vbr_peak". Please refer to "https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/AMF%20Encoder%20Settings%20and%20Tuning%20in%20FFmpeg" for more options.
Now we have an interesting problem. I want to use PreAnalysis because that is supposed to give better predictable frames (p-frames and b-frames) and thus better compression. The suggestion you make here - peak constraint VBR - requires PreAnalysis to be off. So how do i get PreAnalysis AND bitrate control?
Please share your 20Mbit bitstream, and your command line to generate this bitstream so I can help to debug what went wrong. In my local testing I did not see that.
Share bitstream? I can't get the target bitrate, what do you mean? Here's the command i used that does not produce a 20mbit capped file (more like 40mbit):
LD_LIBRARY_PATH=/home/mark/pkgbuilds/ffmpeg/upstream/build/lib \
./ffmpeg -hwaccel amf -hwaccel_device /dev/dri/renderD128 -init_hw_device amf=/dev/dri/renderD128 \
-y -i ~/Videos/eso1706c.avi \
-c:v hevc_amf \
-usage high_quality \
-rc hqvbr \
-qvbr_quality_level 1 \
-minrate 20M \
-maxrate 20M \
-quality quality \
-preset quality \
-profile:v main10 \
-profile_tier high \
-preanalysis 1 -enforce_hrd 1 -filler_data 1 \
-pix_fmt nv12 \
-b:v 20M \
-f matroska test.mkv
The input video is https://cdn.eso.org/videos/ultra_hd_broadcast/eso1706c.avi
Again, and i keep repeating these issues, there are 2 issues:
- The bitrate is not followed (also, don't even think to argue that it needs 40 or 100 mbit, i can get a perfectly nice x265 compression that is around 1mbit on this content with the total file size being just over 1MB).
- the planets jump, some prediction issue. I showed this in the videos i uploaded earlier here https://limewire.com/d/1fce0ed7-de45-4597-829c-afd1840f5da4#SBJk45nsWOC6LdglDKOmqHhlwwT8Q2LvdOemixi2XKQ Did you see that? Were you able to reproduce that?
We will review the document to highlight the differences among different rc modes in future updates.
The HQVBR doc specifically is highly ambiguous and misleading. You can reason both ways. And this part: To guarantee the minimum perceptual quality, and to avoid wasting bit budget, the bitrate accuracy at extremely low/high target bitrate will be reduced. tells absolutely nothing besides being as vague as it can possible be. That's widely open for interpretation. While the very next line for that same setting (HQVBR) reads HQ-VBR aims at improving perceptual quality by producing the constant perceptual quality close to target bitrate. which very definitely makes you think you can control it's bitrate and that AMF will limit itself to the specified bitrate.
I tried the above hqvbr command line with the latest ffmpeg build, "ffmpeg-2025-02-24-git-6232f416b1-full_build", and the resultant bitrate is 21.39Mbps, which is close to 20Mbps.
If you use "-rc vbr_peak", you should be able to achieve the target bitrate with high accuracy.
That is not the result i get. This time with some proof. As apparently uploading the file (which i did before) isn't enough...
The script:
LD_LIBRARY_PATH=/home/mark/pkgbuilds/ffmpeg/upstream/build/lib \
./ffmpeg \
-y -i ~/Videos/eso1706c.avi \
-c:v hevc_amf \
-usage high_quality \
-rc hqvbr \
-minrate 20M \
-maxrate 20M \
-bufsize 20M \
-quality quality \
-preset quality \
-profile:v main10 \
-preanalysis 1 -enforce_hrd 1 -filler_data 1 \
-pix_fmt nv12 \
-b:v 20M \
-f matroska test_hqvbr.mkv
The ffmpeg output:
ffmpeg version N-118470-g3698570442 Copyright (c) 2000-2025 the FFmpeg developers
built with gcc 14.2.1 (GCC) 20240910
configuration: --prefix=/home/mark/pkgbuilds/ffmpeg/upstream/build --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-frei0r --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libdav1d --enable-libdrm --enable-libdvdnav --enable-libdvdread --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgsm --enable-libharfbuzz --enable-libiec61883 --enable-libjack --enable-libjxl --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libplacebo --enable-libpulse --enable-librav1e --enable-librsvg --enable-librubberband --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpl --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-nvdec --enable-nvenc --enable-opencl --enable-opengl --enable-shared --enable-vapoursynth --enable-version3 --enable-vulkan
libavutil 59. 56.100 / 59. 56.100
libavcodec 61. 33.102 / 61. 33.102
libavformat 61. 9.107 / 61. 9.107
libavdevice 61. 4.100 / 61. 4.100
libavfilter 10. 9.100 / 10. 9.100
libswscale 8. 13.100 / 8. 13.100
libswresample 5. 4.100 / 5. 4.100
libpostproc 58. 4.100 / 58. 4.100
Input #0, avi, from '/home/mark/Videos/eso1706c.avi':
Metadata:
date : 2017-02-16T13:00:48.0036
software : Adobe After Effects CC 2017 (Windows)
Duration: 00:00:26.24, start: 0.000000, bitrate: 648060 kb/s
Stream #0:0: Video: hqx (CHQX / 0x58514843), yuv422p16le(10 bpc), 3840x2160, 649039 kb/s, 25 fps, 25 tbr, 25 tbn
Stream mapping:
Stream #0:0 -> #0:0 (hqx (native) -> hevc (hevc_amf))
Press [q] to stop, [?] for help
0125-01-26 01:04:33 879786C0 [AMFEncoderCoreImpl] Warning: PA has already been created!
Output #0, matroska, to 'test_hqvbr.mkv':
Metadata:
date : 2017-02-16T13:00:48.0036
software : Adobe After Effects CC 2017 (Windows)
encoder : Lavf61.9.107
Stream #0:0: Video: hevc, nv12(tv, progressive), 3840x2160, q=2-31, 20000 kb/s, 25 fps, 1k tbn
Metadata:
encoder : Lavc61.33.102 hevc_amf
[out#0/matroska @ 0x5ce0b6795d80] video:133293KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.005290%
frame= 656 fps= 25 q=-0.0 Lsize= 133300KiB time=00:00:26.20 bitrate=41679.1kbits/s speed=1.01x
Terminating internal PA thread
And, new, a bitrate plot! I used this tool with the command:
plotbitrate -o output_hqvbr.svg test_hqvbr.mkv
That gives me this SVG.
It confirms what i've been saying all along, AMF ignores my bitrate settings in these quality VBR modes. Is there anything else i can provide for you to track this issue down?
The way i see it thus far your AMF behaves differently then my AMF. If that is even remotely possible, i don't know. This is on the 7900XT GPU. You work for AMD, you probably can figure out if there is an actual difference between the AMF i use and the one you use.
For your suggestion of vbr_peak. I'll reiterate as you apparently forgot, i want to use preanalysis for better compression. If vbr_peak is the only way to use AMF for video storage encoding then AMF isn't useful for that. In fact, any AMF option that doesn't do preanalysis isn't suitable for storage purposes.
Please be informed that all the preanalysis tools (except qvbr/hqvbr)stated in "https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/AMF%20Encoder%20Settings%20and%20Tuning%20in%20FFmpeg" work with RC mode of vbr_peak.
By the way I tested the above in Windows. I will try it in Linux as well.
You are correct! I missed the TAQ mode. It defaults to 2 on linux. That's probably something you want to fix in the ffmpeg patches as preanalysis in that mode + vbr_peak apparently requires DX11.
0125-01-26 18:31:29 51CEB6C0 [TemporalAdaptiveQuantizer] Error: ../../../../../runtime/src/components/EncodeSDK/TemporalAdaptiveQuantizer.cpp(633):Assertion failed:Init() - AMF_PA_TAQ_MODE_2 is supported on DX11 only.
0125-01-26 18:31:29 51CEB6C0 [AMFPreAnalysisImpl] Error: ../../../../../runtime/src/components/EncodeSDK/AMFPreAnalysisImpl.cpp(1469):AMF_ERROR 4 : AMF_INVALID_ARG: Init() - Temporal Adaptive Quantizer
So adding: -pa_taq_mode 1 to my flags did make the encoding work. However, of the 2 bugs one remains present:
- in vbr_peak the bitrate limitation is adhered to. It's still bugged in the quality modes so don't think it's "fixed" now. It's not. Just not an issue in
vbr_peak. - The issue of the planets jumping around is now present in vbr_peak too. Hinting that
preanalysisdoes something that ruins frames.
You can infer my command... but for completeness i'll post it:
LD_LIBRARY_PATH=/home/mark/pkgbuilds/ffmpeg/upstream/build/lib \
./ffmpeg \
-y -i ~/Videos/eso1706c.avi \
-c:v hevc_amf \
-usage high_quality \
-rc vbr_peak \
-pa_taq_mode 1 \
-minrate 20M \
-maxrate 20M \
-bufsize 20M \
-quality quality \
-preset quality \
-profile:v main10 \
-preanalysis 1 -enforce_hrd 1 -filler_data 1 \
-pix_fmt nv12 \
-b:v 20M \
-f matroska test_vbr_peak.mkv
And the video it generated (now 63MB, we're getting smaller! still waaaay to large). Uploaded here: https://limewire.com/d/5fbc138e-abf7-4090-8061-9455241006e5#BTifxa4v89s117NSVV0K4_N81YpmbnVqgIjWZMzUMx0
We've been going back and forward now for some days on this issue. It kinda baffles me that you try this on windows while you know that AMF has specific features that work on windows and don't work on linux. Why? That's not accurate retesting of what i say. Please be accurate and specific. Please don't give me a feeling like "works for me so not an issue" (i paraphrase), because that is the feeling i do get with your past comments. That feels like wasting my time and effort which i assume is not your intent.
in vbr_peak the bitrate limitation is adhered to. It's still bugged in the quality modes so don't think it's "fixed" now. It's not. Just not an issue in vbr_peak.
Oh, i can try to explain this. It is not really bugged, but, rather, very much intended behaviour.
VBR and CBR are conformant to target bitrate (aka it will follow it closely), while HQCBR/HQVBR/QVBR are not truly conformant (aka they will try, but they may not do it depending on source).
Also... I already asked similar question before). Here is that discussion: https://github.com/GPUOpen-LibrariesAndSDKs/AMF/issues/489
Basically HQCBR/HQVBR use secondary hidden constraint to not "waste" bitrate on low-demanding scenes, neither to overspend bitrate on high demanding ones. To perform that they set perceptual quality by adjusting target quality level of encoding. And target quality overrides target bitrate. ALWAYS. (Same principle as setting qp_min and qp_max, which also override target bitrate)
Meaning that if video is either not very demanding, or too demanding, target bitrate will be ignored as quality would reach desired level. If you still want to get higher quality or target bitrate, Peak Constrained VBR should be used instead (aka PCVBR or, in other interpretations peak_vbr or just VBR)
What that means in practice. If you set target bitrate within range which is suitable for target video, HQCBR/HQVBR allow for some gain in quality on bitrate spikes or demanding scenes (as long as encoder still have bitrate budget available), especially ones that usually cause severe drop in quality for few frames. But it costs you slight reduction on average quality on metrics.
But if your video is too demanding bitrate will go over target... Or if video was not demanding at all, bitrate will be under target. It will try to fit as long as it doesn't hit hard constraint somewhere.
Here are examples:
- On the left, too demanding video (4k gameplay capture), attempted to encode with HQVBR with too low of a target. Target was ignored to preserve minimal perceptual quality.
- On the right, not demanding video (1080p animation fragment), attempted to encode with HQVBR with too high of a target. Target was ignored to preserve bitrate budget.
- And here is example when i set HQVBR so target bitrate and demands of source are within constraints. In this case encoder tried to follow it closely.
...
And QVBR rate control completely ignores target bitrate, as it uses qvbr_quality 1-51 exclusively, not target bitrate. It also has own internal constraints though.
It kinda baffles me that you try this on windows while you know that AMF has specific features that work on windows and don't work on linux.
Well... AV1 HW decode in a whole is only available via DirectX 11 afaik. But i don't think it is fair to assume that everyone knows list of features that are Windows exclusive.
It is a problem though. When people test on Windows and report that it works, because it indeed does work for them. But it doesn't work in Linux. [Frankly speaking, i am Windows user myself in this case, but i can understand frustration]
The issue of the planets jumping around is now present in vbr_peak too. Hinting that preanalysis does something that ruins frames.
I would assume that it is more of a TAQ=2 option specifically in this case? Or does preanalysis in a whole ruins your encode, and not just specific setting? TAQ=2 requires preanalysys to work, but by itself, it is not preanalysis.
UPD: Nah, i saw your encode, even with taq=1 it produced jitter.
And the video it generated (now 63MB, we're getting smaller! still waaaay to large)
-minrate 20M \
-maxrate 20M \
-bufsize 20M \
...
-b:v 20M \
Overall bit rate : 19.9 Mb/s
Video
Bit rate : 19.5 Mb/s
Do i not understand something here? You requested 20 mbps. You got 20 mbps (approx) Size of output is appropriate to requested bitrate. Aka 26 sec * 20 mbps / 8 bits = 520/8 = 65 MB.
That planet jitter is definitely an issue though. Maybe topic should be changed to reflect that?
...
Also... Wait a second...
Did you just used -pix_fmt nv12 \ with -profile:v main10 \ ?
I may be wrong, but i don't think it is a way how it supposed to work.
Main10 profile enforces 10 bit encode (unlike Main which can encode as 8 or 10 bit depending on request)
But 10 bit requires P010 pixel format afaik. Not NV12...
Aaand i checked. You somehow managed to encode strictly 10-bit format as 8-bit because of your pixel format enforcement.
Format profile : Main [email protected]@Main
Bit depth : 8 bits
Moreover... 10 bit encodes do not currently work with preanalysis (and never worked i believe). At all! It supposed to error out. You only allowed to use preencode for 10-bit, as preanalysis does not support it.
Hi @DimkaTsv Thank you for your extremely detailed response! That is so much appreciated 👍
The more i "understand" about the "quality" levels in AMF (them being QVBR, HQVBR and HQCBR) the less they make sense. Am i falling into the classical pitfall of more knowledge only means more questions? hehe. Joking aside, these modes a loaded with assumptions that are either not described or are themselves so vaguely described that they still say nothing. Why on earth would you want to have such vague setting? .. It is mind blowing to me. I haven't seen or heard a single good reason for their existence with the characteristics that they have. And their names very definitely don't reflect their usage pattern!
HQVBR (and the other quality ones). My expectation: the codec following my settings and trying it's best to create a result that matches it as closely as possible. It might be slower, like analogous to setting a higher quality preset akin to x265 to for example the slow mode. But what do you get instead? Well.. that's a surprise based on your content and a surprise you definitely won't expect.
I would assume that it is more of a TAQ=2 option specifically in this case? Or does preanalysis in a whole ruins your encode, and not just specific setting? TAQ=2 requires preanalysys to work, but by itself, it is not preanalysis.
I literally cannot test that. I must set both to even have a working encoder.
Do i not understand something here? You requested 20 mbps. You got 20 mbps (approx) Size of output is appropriate to requested bitrate. Aka 26 sec * 20 mbps / 8 bits = 520/8 = 65 MB.
Ha, nicely spotted! Oke, in those specific settings (all set at 20Mb/sec) that was expected to be the result. I should change the rates a lot to reflect what i do expect. That would be an output of somewhere around 1MB (megabyte). So you can put that slightly bad test in the "he's frustrated with this damned encoder and just tried to get something working" folder ;)
That planet jitter is definitely an issue though. Maybe topic should be changed to reflect that?
Yeah, that should be a new issue. The current issue of the encoder not following my settings still is the main issue here. Then again, with your explanation it seems like this is intended behavior. Which to me would make these preset completely useless.
Also... Wait a second... Did you just used -pix_fmt nv12 \ with -profile:v main10 \ ? I may be wrong, but i don't think it is a way how it supposed to work. Main10 profile enforces 10 bit encode (unlike Main which can encode as 8 or 10 bit depending on request) But 10 bit requires P010 pixel format afaik. Not NV12...
That is for preanalysis, it requires nv12. If i disable that (which defeats the whole purpose for me) then i can indeed use P010.
Moreover... 10 bit encodes do not currently work with preanalysis (and never worked i believe). At all! It supposed to error out.
It does hence setting it to nv12.
I want 10 bit output to give more encoder room for gradients. Why? Because of freaking banding! Granted, a good codec shows barely any banding on 8 bit. However, i found that simply forcing 10 bit reduces the banding problems to virtually nothing. This image (from this article) shows it a little more pronounced but this is what i absolutely hate (and see in every youtube video these days). For years the general advice against banding is to just use 10 bit encoding, it prevents the issue (depending on the source) and has nearly no downsides.
The more i "understand" about the "quality" levels in AMF (them being QVBR, HQVBR and HQCBR) the less they make sense.
Well, just don't overcomplicate it. Assume that HQVBR and HQCBR allow for less spiky frame to frame quality (within HW encoder capabilities, of course), while still conforming to bitrate, unless target bitrate is way off mark. If it is way off mark, it will try to use least possible to keep either minimal quality level, or smallest size within quality range.
QVBR on other hand, is closer to CRF. But as it is not CRF (actually QVBR as idea originally stems from Amazon and AMD implementation is basically own twist on it), it uses it's own set of parameters and different quality scale. Also, unlike CQP, QVBR 1 and 51 quality are not correspond to CQP 51 and 1 respectively. QVBR range is noticeably smaller (something around 42-23 CQP).
Am i falling into the classical pitfall of more knowledge only means more questions? hehe. Joking aside, these modes a loaded with assumptions that are either not described or are themselves so vaguely described that they still say nothing.
Well... Let me ask you what Intel ICQ does then?) And how is it different from LA-ICQ. And what is their relation to CRF? (Because it is Intel's twist on CRF). ... And what is AVBR, or LA rate control (lookahead, but how is it rate control. And what difference are compared to LA-HRD)... Or VCM? [Btw, sheesh... Seems like Intel made even more weird encode modes since i last checked]
Will also note than NVENC supports QVBR mode too. Granted no idea about behaviour, as i don't own Nvidia GPU currently.
Why on earth would you want to have such vague setting? .. It is mind blowing to me. I haven't seen or heard a single good reason for their existence with the characteristics that they have. And their names very definitely don't reflect their usage pattern!
That can be said about a lot of things. Short answer. Engineer logic. For them it makes sense.
I literally cannot test that. I must set both to even have a working encoder.
Because HQVBR REQUIRES preanalysis. And TAQ is preanalysis suboption.
HQVBR (and the other quality ones). My expectation: the codec following my settings and trying it's best to create a result that matches it as closely as possible. It might be slower, like analogous to setting a higher quality preset akin to x265 to for example the slow mode. But what do you get instead? Well.. that's a surprise based on your content and a surprise you definitely won't expect.
As with many things in video encoding. It depends. But do not say that it is a surprise. Behaviour is documented.
https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/Rate-Control-Methods
This mode sets the RC mode to HIGH_QUALITY_VBR. It is based on AMD patented technology on constant quality video coding.
Which should hint you, that QP take priority here.
HQ-VBR aims at improving perceptual quality by producing the constant perceptual quality close to target bitrate. To guarantee the minimum perceptual quality, and to avoid wasting bit budget, the bitrate accuracy at extremely low/high target bitrate will be reduced.
And this should tell you exactly what will happen. Moreover, i will also say, that VBR also is not fully conformant to follow target bitrate. It must create buffer from somewhere. If target is exceptionally easy to encode, it will greatly reduce bitrate on it. Like static images, for example. Even CBR by default does not follow target bitrate, you know. Only if you enable filler data and force HRD compliance. Which should be enabled by default... (Otherwise it will be just VBR with some VBV buffer strictness difference iirc.) But not every app does this)
It's not like i don't understand your reasoning. But just use VBR + preanalysis in this case. It's not like you must use HQVBR all the time. It is option for a reason. And it costs not insignificant amount of performance.
Issue why your wish is not possible to make, is inflexibility of hardware encoder. They don't really allow much of an adjustment. That is why software encode ALWAYS is better than hardware one. With hardware you trade quality for speed. These alternate quality mode allow for slightly different behaviour of encoder, allowing users to have slightly more choice.
Without HQVBR, your only choice would've been to constraint min/max QP manually, and even then, VBR by nature doesn't keep lasting buffer. It agressively spends what it gathers on any opportunity. HQVBR instead more agressively creates buffer whenever it is possible without much damage and spends it more conservatively.
That is for preanalysis, it requires nv12. It does hence setting it to nv12.
That's the point. NV12 BY DEFINITION is 8 bit depth format. Quite literally. While P010 is 10 bit format https://learn.microsoft.com/en-us/windows/win32/medfound/10-bit-and-16-bit-yuv-video-formats
You cannot encode 10 bit output with NV12. Because NV12 is short for YUV 420 8-bit. [P010 is short for YUV 420 10-bit]
And i just provided mediainfo snippet from your output which stated that it was 8 bit encode.
What you did, is broke Main10 profile, which requires forced 10 bit, by forcing it encode in 8 bit mode. And preanalysis worked specifically because encode was forced to 8 bit mode in background.
I want 10 bit output to give more encoder room for gradients. Why? Because of freaking banding! Granted, a good codec shows barely any banding on 8 bit. However, i found that simply forcing 10 bit reduces the banding problems to virtually nothing. This image (from this article) shows it a little more pronounced but this is what i absolutely hate (and see in every youtube video these days). For years the general advice against banding is to just use 10 bit encoding, it prevents the issue (depending on the source) and has nearly no downsides.
Understandable. But do not try and play games with settings. What you see with your planet jitter may very well be bug caused by your crafty hands and breaking encoder by forcing it to use incompatible options via way that devs hadn't thought about and locked off.
There are no workarounds to use AMF preanalysis with 10-bit encodes. It won't work... If it did somehow, that means that you broke something.
In similar way (not 1:1, just similar) YUV 422 or 444 won't work on AMD hardware, because there is no physical support. Why mentioning this? Because YUV 444 encode is second way to preserve color quality.
And it's not like there are no downsides to using 10-bit. Compatibility, for one. With hardware it is less of an issue now, as most modern stuff can decode 10 bit (it wasn't always like that though). But when uploading to some services 10 bit source may potentially cause some issues And fact that you are limited to using preencode (which maybe shouldn't even be used, imo), for another potential downside.
And third... Where would you even use these videos, if banding is such an issue? YouTube? It will recompress them anyways. What you see as "banding" in YouTube is mostly artifact that comes from recompression to lower bitrate. They give small YouTubers something, like AVC 450-600 kbps bitrate for 1080p videos. Only workaround is to encode 1440p+ (better 4k) to snatch higher (up to around 4.5k) bitrate with VP9/AV1. Twitch? You will be forced to use low bitrate, which is main reason why banding and compression artifacts will happen.
And fourth... Is banding with 8-bit REALLY as big of an issue as you picture it? Or is it just min-maxing desire? Here, let me show you. This is my screen capture of gradient. And probably worst case scenario out there. Left one is screen capture of image directly. Output bitrate was 4.5 mbps Right one is screen of reencoded capture. Output bitrate was 457 kbps. (Even with CBR, unless i use CBR+filler) Both were made as 8-bit encode.
And here is 8 bit reencode vs 10 bit reencode. 8-bit one is 457 kbps, while 10 bit one is 634 kbps (10 bit is less efficient at small bitrates afaik, but give it slack). Both were encoded at same target bitrate, i only changed Main profile to Main10.
You can try to guess which is which, if you want...
But my point was... Is there really that much of a loss to worry about? Is difference really THAT significant? Most changes could even be thrown under the bus on that small gain in bitrate.
Don't get me wrong, it's not completely invisible, especially under some movement. But it is pretty much at level of insignificance. They look way more like compression artifact rather than banding. Which, coincidentally, is way more pronounced on YouTube as it both forces reencode, and uses quite low bitrates at that. (And will say though. For bitrates they use, some of encodes look gorgeous... Not AVC ones though, AV1 or VP9 ones. But average person won't get those, unless it uploads 1440p or higher resolution)
Well... Let me ask you what Intel ICQ does then?) And how is it different from LA-ICQ. And what is their relation to CRF? (Because it is Intel's twist on CRF). ... And what is AVBR, or LA rate control (lookahead, but how is it rate control. And what difference are compared to LA-HRD)... Or VCM? [Btw, sheesh... Seems like Intel made even more weird encode modes since i last checked]
Will also note than NVENC supports QVBR mode too. Granted no idea about behaviour, as i don't own Nvidia GPU currently.
Yeah, no clue. Don't have Intel nor NVIDIA. I'm playing a lot with AMF settings thus i feel like i know more and more about it. But that "knowing more" doesn't make it easier.
But do not say that it is a surprise. Behaviour is documented.
...
And this should tell you exactly what will happen.
It's documented. Open for interpretation and the documentation contradicts itself. Or it doesn't contradict but it's true "from a certain point of view" ... In other terms, it might as well be undocumented.
You cannot encode 10 bit output with NV12. Because NV12 is short for YUV 420 8-bit. [P010 is short for YUV 420 10-bit]
And i just provided mediainfo snippet from your output which stated that it was 8 bit encode.
You're probably testing with the wrong video file. I think i posted a wrong link early on and you still use that. The video i was testing this on was this one: https://cdn.eso.org/videos/ultra_hd_broadcast/eso1706c.avi It has a pixel format of yuv422p16le.
And it's not like there are no downsides to using 10-bit. Compatibility, for one. With hardware it is less of an issue now, as most modern stuff can decode 10 bit (it wasn't always like that though). But when uploading to some services 10 bit source may potentially cause some issues
Yeah, let's not go there. I hate youtuibe for literally al it's videos being horribly bad in regards to banding. Hardware isn't an issue and in todays world - we live in 2025! - it's time to move on to better standards. 10 bit video encoding should be the norm and minimal.
And fourth... Is banding with 8-bit REALLY as big of an issue as you picture it? Or is it just min-maxing desire? Here, let me show you. This is my screen capture of gradient. And probably worst case scenario out there. Left one is screen capture of image directly. Output bitrate was 4.5 mbps Right one is screen of reencoded capture. Output bitrate was 457 kbps. (Even with CBR, unless i use CBR+filler) Both were made as 8-bit encode.
Your examples are all wrong, sorry :) Showing these color spectrum gradients like you did isn't showing the banding issue proper. It's in scenes where there is one color that fades to something lighter or darker where banding becomes really pronounced. Think of the classical sunset views. I'll show some - horribly bad - youtube shots from popular creators. Level1tech intro:
LTT (ironically about the newest AMG gpu)
I checked, those were with av1 (so codec wise not comparable) but yet again. 8 bit. It's hard to find actual 10 bit on youtube if it even exists. You can be darn sure that those renders of these animations don't show banding. It's low bitrate encoding amplifying it and 8 bit causing it.
I especially see it in space themed videos (like this one https://www.youtube.com/watch?v=1XIsGx7tAsY and then nearly every animation that it plays). Which is why i took a space render source because i know it's quality and i want to preserve it at that quality! But that's just as a test case to see if AMF is capable (which it seems to be if i only look at banding).
I'll show some - horribly bad - youtube shots from popular creators.
You didn't hear me, right? YouTube doesn't really care about your source. It ALWAYS reencodes it with own parameters. And oops, you will end up with 8-bit output anyways. On top of mediocre bitrate.
You're probably testing with the wrong video file. I think i posted a wrong link early on and you still use that. The video i was testing this on was this one: https://cdn.eso.org/videos/ultra_hd_broadcast/eso1706c.avi It has a pixel format of yuv422p16le.
It does not matter. Well, in the first place, your source can only be created via SW encode or decidated encoder. Because 422 16 bit capture is not even close to being widely adopted format..
In the second place. I literally checked your output, not source. I hadn't tried to encode it myself, i just downloaded your output and looked into mediainfo it reports. And it reports 8-bit. With Main10 profile. Which should not ever be a thing. That is what i had been pointing out to.
So you did encode 8-bit video in the end. But it reported Main10 profile for some reason.
Your examples are all wrong, sorry :) My examples were made by me, literally. I understand that you mean banding on very shallow gradients, ok. They will have issue more pronounced because, duh, compression. And likely it is not what their source had.
For example... Linus AMD video you referred to, was reencoded by YouTube into...
401 mp4 3840x1920 30 │ 290.00MiB 3498k https │ av01.0.12M.08 3498k video only
3.5 mbps for 4k30 video? Don't you think it is quite low? Yup, because YouTube reencoded source video.
And latest Level1Tech video with intro you showed was encoded as...
401 mp4 3840x2160 30 │ 518.75MiB 4787k https │ av01.0.12M.08 4787k video only What, 4.8 mbps for 4k video? Again?
And don't get me wrong, there are higher quality encodes. Like these (don't really think about these 16 and 18.5 mbit videos, they are actually same as webm ones, it is just issue with fragmented streams compared to continious ones):
[For LTT video]
625 mp4 3840x1920 30 │ ~ 1.29GiB 15939k m3u8 │ vp09.00.50.08 15939k video only IOS 313 webm 3840x1920 30 │ 611.36MiB 7375k https │ vp09.00.50.08 7375k video only 2160p, IOS, webm_dash
[For L1T video]
625 mp4 3840x2160 30 │ ~ 1.98GiB 18669k m3u8 │ vp09.00.50.08 18669k video only IOS 313 webm 3840x2160 30 │ 1.02GiB 9618k https │ vp09.00.50.08 9618k video only 2160p, IOS, webm_dash
But YouTube won't just give those to you when you click on video. Those are hidden and not easily accessible. Moreover, those are still reencodes. Afaik for premium users, maybe?
Only those who upload videos can get them back, if they request their data from Google. (Yeah, it also includes sources of everything you ever uploaded to Google. Was surprised to know, but i got back video i recorded and uploaded something like 11 years ago. Not sure about stream VOD's though.)
And i will also say, as someone who just downloaded these to check. They also have banding. Even though it is less "squared" on borders.
... ...
Also, WTH is that source? First time ever i saw MPC-HC choke on format. First time PotPlayer actually helped me, so i am forced to give credit to that guy who forced it with all he could. Canopus HQX? Is it some sort of a a-la RAW format codec? Well, on such source (which is at this point very high quality, well duh it is 422 16 bit source) 10 bit encode will be more efficient. Will give you that. It is not your day to day NV12 video (which is most common pixel format).
Personally checked and with 8-bit i do get small amount of visible banding on star light (same amount as in your jittering sample), while on 8 bit i did not. But this source is more of an exception than rule. In most day to day cases, there won't be such high quality source on hand.
But still, will say you that. As video in source smoothly and slowly flowing, it is not hard to encode. Meaning you don't even need preanalysis, really. There are no scene transitions or rapid movements happening. Moreover, even 10 mbps bitrate is overkill for sample you sent it seems. Even VBR does not give output more than 5 mbps.
Alright, let's not take things too literal here. I'm showing examples of my beef (banding) and my intent (good quality in a small file size) encodes.
I know youtube is horrible. I know the yuv422 16 bit example is a monster.
Neither are the intended goal beyond being an example.
The intent here is more the case of a creator uploading their video and the site presenting it in a good quality. Like youtube but just better. If your video isn't action loaded then a 4k video should be of perfect quality where you average the bitrate at 5mbit/sec and potential peaks to 10mbit/sec.
And for that intent you want b and p frames (prediction frames) because they improve compression. And for that you need preanalysis to be on. Which circles back to my original issue. I was expecting the quality versions of AMF to be able to do this or at least approach being able to do this. Or phrased differently, if i encode my example space video (the one that chokes your pc) with x265:
LD_LIBRARY_PATH=/home/mark/pkgbuilds/ffmpeg/upstream/build/lib \
./ffmpeg \
-y -i ~/Videos/eso1706c.avi \
-c:v libx265 \
-minrate 1M \
-maxrate 10M \
-crf 22 \
-profile:v main10 \
-preset slow \
-pix_fmt yuv420p10 \
-b:v 5M -bufsize 5M \
-f matroska test_x256.mkv
It gives me this bitrate profile:
It's size? Just 3.8MB. And that's without tuning the encoding parameters.
And looks absolute perfect and indistinguishable from the source. That - or approaching that - is what i was expecting from the quality presets in AMF.
I know youtube is horrible. Hardware isn't an issue and in todays world - we live in 2025! - it's time to move on to better standards. 10 bit video encoding should be the norm and minimal.
Another reason for why not 10-bit. Imagine, that HEVC is a codec that required royalties to pay (and still does? At least in Microsoft Store license costs 1$). AV1 hasn't been out yet. (VP9 was only one available) And most hardware did not support 10-bit decode. Especially as AVC 10-bit is such an obscure profile that barely anything even supports it (but it exists) Frankly speaking even Intel 6-th Gen CPU's and Nvidia 1060 did not support 10-bit decode (1070 and 1080 did, though, for some reason)
Meaning that first widely available hardware that supported 10 bit decode were RTX 20XX/16XX and Intel 7000 series. Which were released in 2019 and 2017 respectively. So... Only 6-8 years past at most? It is so little in a world of standards. I would assume that quite a lot people don't have access to HW accelerated 10 bit decode even at the current day.
And for that intent you want b and p frames (prediction frames) because they improve compression. And for that you need preanalysis to be on.
Nope... That is not how it works.
- You won't get B-frames on AMD hardware unless you use AVC and explicitly set usage of B-frames. (Or AV1 with RX 9000 series, which will be released in few days from now). And AVC only supports 8 bit encode.
- You will get I/P frames no matter what you do. I-frame = Key frame (in case of HW encode). P-frame = everything else. Meaning that you will get... Well, depends on settings. From 11 to 599 P-frames per I-frame. Can make it even more via GOP length.
- AV1 doesn't even have technical I/P/B frames. It has Intra and Inter frames instead. (Will probably still have B-frames though... for some reason)
- Preanalysis job is to help encoder predict quantization level it should apply to specific frames to preserve relative quality. Quantization = removing noise. Noise in encoding is basically pixels that don't have specific pattern or frequency.
- TAQ is responsible for frame to frame quality transition. Usually encoder rapidly switch quality levels on each frame. TAQ=2, for example, makes metric graph look smooth and not jagged, meaning that frame to frame difference is minimized.
It's size? Just 3.8MB. And that's without tuning the encoding parameters.
Well, it is hard to compare HW encoder to SW one. Remember? Trading quality for speed. Or, size for speed. Basically... You are always playing "pick 2 out of 3" game. Quality / File size / Speed.
If your video isn't action loaded then a 4k video should be of perfect quality where you average the bitrate at 5mbit/sec and potential peaks to 10mbit/sec.
While with 3.8 MB size of output file it is quite unlikely to have as good of quality as software encode (it is 1200 kbps), with 5 mbps it should be pretty doable. Here is example. (Sorry, i needed to trick encoder to think source was .mkv and not .avi because it messed up framerate in mediainfo)
So it is pretty much doable. And it was 10 bit encode as well.
Will say though... With such video do not trust that VMAF score without looking at video. 1500 kbps one had quite noticeable compression artifacts close to star. (aka everything was blocky/squared with small segments) Granted on 5000 kbps one you could still notice small amount of blockyness around star at very first frames, but then it smoothened out to almost imperceptible level.
Granted, i am not using ffmpeg, but VCEEnc (ignore everything past bitrate, these are to copy data from source if there is one. These are prewritten in my script):
-i "C:\Users\-----\Videos\test sample\eso1706c.mkv" -o "eso1706c_processed.mkv" --avsw --codec HEVC --profile main10 --tier high --level 6.2 --preset slow --vbr 1500 --max-bitrate 4500 --colormatrix auto --colorprim auto --transfer auto --audio-copy --chapter-copy --sub-copy --colorrange auto
-i "C:\Users\-----\Videos\test sample\eso1706c.mkv" -o "eso1706c_processed.mkv" --avsw --codec HEVC --profile main10 --tier high --level 6.2 --preset slow --vbr 1500 --max-bitrate 4500 --colormatrix auto --colorprim auto --transfer auto --audio-copy --chapter-copy --sub-copy --colorrange auto
Does this look fine to you? (From 5000 kbps encode)
Well, it is hard to compare HW encoder to SW one. Remember? Trading quality for speed. Or, size for speed. Basically... You are always playing "pick 2 out of 3" game. Quality / File size / Speed.
I am! Slightly bigger file size, quality and speed seem like a nice tradeoff. However. What i get is massively blown up size and that's just not whet i want. Just an arbitrary percentage but say x265 does this in 1200 kbps on average then i expect AMF to be in the higher end but still in the ballpark. So say +25% which would make it average at around 1500. Not 5000 or even 20000... Mind you, it's visually worse on AMF too. Not specifically in this example but i had another (this one - 4GB! - this is the video) example with a little more gradient effects where AMF would add in pixelated noise even on a high bitrate. The gradient in the "shelf" (it makes sense of you see it) on the left edge side is just ruined by AMF.
Will say though... With such video do not trust that VMAF score without looking at video. 1500 kbps one had quite noticeable compression artifacts close to star. (aka everything was blocky/squared with small segments)
I always look at the images itself and judge based on that. I don't even care that much about vmaf though it helps in finetuning when you already found a near acceptable setting and just tweak parameters.
Granted on 5000 kbps one you could still notice small amount of blockyness around star at very first frames, but then it smoothened out to almost imperceptible level.
But that is simply unacceptable. It is acceptable in a bitrate ladder kind of setting where you're going up/down the ladder based on your internet connection. You just can't have this in a normal video.
Does this look fine to you? (From 5000 kbps encode) A still doesn't say anything about the video quality ;) 1 frame could be perfect while the video itself is full of artifacts.. Yes, this still looks fine in this out of context case.
What i get is massively blown up size and that's just not whet i want. So say +25% which would make it average at around 1500. Not 5000 or even 20000... Mind you, it's visually worse on AMF too.
There is small problem with your expectations. Due to HW encoders inflexibility, low bitrate encode always were their worst case scenario. And VCN is one which is even worse in that than competition (yes i said that, VCN is not that great at low bitrate encodes) Especially as you want to preserve as much of a color data as possible. If you want max quality for size, then go for SW encode 100% of the time.
HW to SW encoder with low to medium bitrates would assume something around +40 +60% bitrate to compare on average (but depending on source can be less than that). And even then, HW encoder often designed to prioritize bitrate constraint over quality, because one of it's use is streaming.
So there is not just a SLIGHT trade for size. It is actually quite significant, especially at lower bitrates. Up to until 3000 kbps i would use +50-100%. 3000 and more i would use +30-50% to target bitrate relative to expected SW encode, depending on source. After something like 10000-15000 kbps you may want to just equal them or add +25%. At some point recompression induced loss would be at level, where bitrate increase does not matter. But point where it happens will always depend on source.
But that is simply unacceptable. It is acceptable in a bitrate ladder kind of setting where you're going up/down the ladder based on your internet connection. You just can't have this in a normal video.
That is just how HW encoder works without preprocessing. Because when i had done these encodes, i didn't specify one. HW encoders don't have brains to dynamicaly adjust parameters on the fly. So it will try to slightly overconstraint first few frames, because in 90+% cases (just number from head) they are black screens. And by SLIGHT blockiness, i actually meant slight one. Do you really expect people to stopframe first 0.25 seconds and look closely with video full screened?
If you want to remove it or make it as imperceptible as possible, you are free to try and use preencode option, as, unlike preanalysis, it does work with 10 bit encodes. (It should help with these first frames). I didn't used one when i tested those. When i tried with it, first frames were a lot smoother.
Not specifically in this example but i had another (this one - 4GB! - this is the video) example with a little more gradient effects where AMF would add in pixelated noise even on a high bitrate. The gradient in the "shelf" (it makes sense of you see it) on the left edge side is just ruined by AMF.
Not sure about what shelf you talked about. Here is transcoded to 4514 kbps output. (i used VBR 5000, but oh well, source wasn't one to get VBR to have precise bitrate)
I would say that your second potential issue is red precision. But that red->black transition will get crushed. It is slightly better with higher bitrate, but still visible.
Here is example of what i meant.
Anyways, we strafed from target. It all started from fact, that your supposedly 10 bit encode, wasn't actually 10 bit. That you managed to break Main10 preset, by forcing it into 8 bit via enforcment of NV12 pixel format. And that it was probably reason for jittering, and you should've tested different command setups.
In addition i provided you samples of actual 10 bit encodes, where banding is much less pronounced. So i suggested that your issue was mainly in fact that you, in attempts to make preanalysys work somehow broke encode and it fell back from 10 bit to 8 bit and ended up reintroducing banding. And tried to explain that preanalysis, while good on average, is not as significant for your purposes as you thought originally, so you could just encode 10 bit directly.
Not sure about what shelf you talked about. Here is transcoded to 4514 kbps output. (i used VBR 5000, but oh well, source wasn't one to get VBR to have precise bitrate)
You got it exactly at the point what i meant. Interesting though that you don't have noise where i did. Hmm..
Anyways, we strafed from target. It all started from fact, that your supposedly 10 bit encode, wasn't actually 10 bit. That you managed to break Main10 preset, by forcing it into 8 bit via enforcment of NV12 pixel format. And that it was probably reason for jittering, and you should've tested different command setups.
Do not assume! If I've learned one thing here in this thread and with AMF in general is that assumptions really never work. As it is in this case, i just tried! main10 or main, no difference, the jitter remains. Same source and nv12. My stream properties:
Stream #0:0: Video: hevc (Main), yuv420p(tv, progressive), 3840x2160 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 1k tbn
So yes, i really tried it with main too. I can upload the video again but i don't really see a point in doing that again.
Now your next suggestion might be "perhaps it's the source"... as why not, it would make sense to suggest that. So i tried that other video (what i called the shelf) too. And, surprise, it has the exact same issue.
What is new though is AMF crashes during encoding!
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/mark/Videos/potw2423a.mov':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2024-05-27T13:32:52.000000Z
Duration: 00:00:50.56, start: 0.000000, bitrate: 673525 kb/s
Stream #0:0[0x1](eng): Video: prores (HQ) (apch / 0x68637061), yuv422p10le(bt2020nc/bt2020/arib-std-b67, progressive), 3840x2160, 671823 kb/s, SAR 1:1 DAR 16:9, 25 fps, 25 tbr, 25 tbn (default)
Metadata:
creation_time : 2024-05-27T13:32:52.000000Z
handler_name : Apple Video Media Handler
vendor_id : appl
encoder : Apple ProRes 422 HQ
timecode : 00:00:00:02
Stream #0:1[0x2](eng): Audio: pcm_s16le (sowt / 0x74776F73), 48000 Hz, stereo, s16, 1536 kb/s (default)
Metadata:
creation_time : 2024-05-27T13:32:52.000000Z
handler_name : Apple Sound Media Handler
vendor_id :
timecode : 00:00:00:02
Stream #0:2[0x3](eng): Data: none (tmcd / 0x64636D74) (default)
Metadata:
creation_time : 2024-05-27T13:32:52.000000Z
handler_name : Time Code Media Handler
timecode : 00:00:00:02
Stream mapping:
Stream #0:0 -> #0:0 (prores (native) -> hevc (hevc_amf))
Stream #0:1 -> #0:1 (pcm_s16le (native) -> vorbis (libvorbis))
Press [q] to stop, [?] for help
0125-02-02 22:52:02 18E616C0 [AMFEncoderCoreImpl] Warning: PA has already been created!
Output #0, matroska, to 'test_vbr_peak_pa1.mkv':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
encoder : Lavf61.9.107
Stream #0:0(eng): Video: hevc, nv12(tv, bt2020nc/bt2020/arib-std-b67, progressive), 3840x2160 [SAR 1:1 DAR 16:9], q=2-31, 20000 kb/s, 25 fps, 1k tbn (default)
Metadata:
encoder : Lavc61.33.102 hevc_amf
creation_time : 2024-05-27T13:32:52.000000Z
handler_name : Apple Video Media Handler
vendor_id : appl
timecode : 00:00:00:02
Stream #0:1(eng): Audio: vorbis (oV[0][0] / 0x566F), 48000 Hz, stereo, fltp (default)
Metadata:
encoder : Lavc61.33.102 libvorbis
creation_time : 2024-05-27T13:32:52.000000Z
handler_name : Apple Sound Media Handler
vendor_id :
timecode : 00:00:00:02
[hevc_amf @ 0x5cbeeaf1cb40] Data acquired but delayed SubmitInput returned AMF_INPUT_FULL- should not happen
Last message repeated 1 times
0125-02-02 22:52:02 827FD6C0 +1= 50944KiB time=00:00:22.48 bitrate=18564.6kbits/s speed=1.32x
0125-02-02 22:52:19 827FD6C0 [AMFDeviceVulkanImpl] Error: ../../../../../runtime/src/core/DeviceVulkanImpl.cpp(3751):Assertion failed:FinishQueue() failed call vkQueueWaitIdle(), Error=1
0125-02-02 22:52:25 82FFE6C0 +2= 50944KiB time=00:00:22.48 bitrate=18564.6kbits/s speed=0.977x
0125-02-02 22:52:25 82FFE6C0 [FeatureGenerator] Error: ../../../../../runtime/src/components/EncodeSDK/FeatureGenerator.cpp(902):AMF_ERROR 1 : AMF_FAIL: m_spComputeDevice->FinishQueue()
0125-02-02 22:52:25 82FFE6C0 [FeatureGenerator] Error: ../../../../../runtime/src/components/EncodeSDK/FeatureGenerator.cpp(489):AMF_ERROR 1 : AMF_FAIL: Process_RetrieveData(surfaceData.spNativeCopy, pFGENProperties, pFGENData)
0125-02-02 22:52:25 82FFE6C0 [AMFPreAnalysisImpl] Error: ../../../../../runtime/src/components/EncodeSDK/AMFPreAnalysisImpl.cpp(469):AMF_ERROR 1 : AMF_FAIL: Error occured in FGEN Process
0125-02-02 22:52:28 19E636C0 [AMFDeviceVulkanImpl] Error: ../../../../../runtime/src/core/DeviceVulkanImpl.cpp(3751):Assertion failed:FinishQueue() failed call vkQueueWaitIdle(), Error=1
0125-02-02 22:52:28 82FFE6C0 [AMFDeviceVulkanImpl] Error: ../../../../../runtime/src/core/DeviceVulkanImpl.cpp(3840):Assertion failed:FlushQueue() failed to vkQueueSubmit(), err = -4
0125-02-02 22:52:29 82FFE6C0 [AMFDeviceVulkanImpl] Error: ../../../../../runtime/src/core/DeviceVulkanImpl.cpp(3751):Assertion failed:FinishQueue() failed call vkQueueWaitIdle(), Error=-4
0125-02-02 22:52:29 82FFE6C0 [HierarchicalMotionEstimation] Error: ../../../../../runtime/src/components/EncodeSDK/HierarchicalMotionEstimation.cpp(866):AMF_ERROR 1 : AMF_FAIL: m_spComputeDevice->FinishQueue()
0125-02-02 22:52:29 82FFE6C0 [HierarchicalMotionEstimation] Error: ../../../../../runtime/src/components/EncodeSDK/HierarchicalMotionEstimation.cpp(367):AMF_ERROR 1 : AMF_FAIL: Process_RetrieveData(surfaceData.spNativeCopy, pHMEProperties, pHMEData)
0125-02-02 22:52:29 82FFE6C0 [AMFPreAnalysisImpl] Error: ../../../../../runtime/src/components/EncodeSDK/AMFPreAnalysisImpl.cpp(519):AMF_ERROR 1 : AMF_FAIL: Error occured in HME Process
./reencode.sh: line 17: 119481 Segmentation fault (core dumped) LD_LIBRARY_PATH=/home/mark/pkgbuilds/ffmpeg/upstream/build/lib ./ffmpeg -y -i ~/Videos/potw2423a.mov -c:v hevc_amf -usage high_quality -rc vbr_peak -pa_taq_mode 1 -minrate 20M -maxrate 20M -bufsize 20M -quality quality -preset quality -preanalysis 1 -enforce_hrd 1 -filler_data 1 -preencode 1 -pix_fmt nv12 -b:v 20M -f matroska test_vbr_peak_pa1.mkv
But doing the same encode again didn't give me crashes and gave me still the same results. Main or main10 has nothing to do with this. 8 or 10 bit, same story.
Do not assume! If I've learned one thing here in this thread and with AMF in general is that assumptions really never work. As it is in this case, i just tried! main10 or main, no difference, the jitter remains. Same source and nv12. My stream properties: But doing the same encode again didn't give me crashes and gave me still the same results. Main or main10 has nothing to do with this. 8 or 10 bit, same story.
Ok, this new info does give issue some progress. So it doesn't matter if you use Main or Main 10. What else can be a factor, then... Because something must cause this in the first place.
I cannot test it myself, as i don't have Linux installed beside WSL, and i cannot use it for such purposes.
These are options you used...
LD_LIBRARY_PATH=/home/mark/pkgbuilds/ffmpeg/upstream/build/lib \
./ffmpeg \
-y -i ~/Videos/eso1706c.avi \
-c:v hevc_amf \
-usage high_quality \
-rc vbr_peak \
-pa_taq_mode 1 \
-minrate 20M \
-maxrate 20M \
-bufsize 20M \
-quality quality \
-preset quality \
-profile:v main10 \
-preanalysis 1 -enforce_hrd 1 -filler_data 1 \
-pix_fmt nv12 \
-b:v 20M \
-f matroska test_vbr_peak.mkv
I will try to go through them.
Overwrite output, input file X.
Copy video with reencode via hevc_amf
Use PCVBR
Set preanalysis to enabled, TAQ mode - 1
Min bitrate - 20 mbps (i don't think that AMF has `-min_rate` option)
Max bitrate - 20 mbps (it does have `max_rate` option, though)
VBV buffer size - 20 mbps
Quality preset - quality
Quality preset - quality (yes, `-quality` and `-preset` are same thing, but i had made same mistake at some point)
Profile - Main/Main10 (both had been tried out)
Enable preanalysis, Enforce HRD compliance, Enable usage of filler data
Pixel format - NV12 (aka 8 bit YUV 420)
Target bitrate - 20 mbps.
Output container - Matroska, file name Y
So... From my stantpoint there should be nothing that wrong or suspicious besides that pixel format enforcement. As long as you not trying to push 10 bit mode with 8 bit pixels. (Which should've been avoided via Main profile instead of Main10)
I guess you can try some baseline encode? Without forcing formats HRD and preanalysis. If it doesn't behave same, add options one by one until it starts jittering again. Then remove options in different order, until it disappears. (sometimes combination of options can cause that)
Sorry for being unable to properly test stuff, due to OS difference. Aka it might be Linux specific problem. And as i am not developer, i doubt i can decifer what error code you encountered means. Except... Maybe some issue with processing with Vulkan acceleration? Hadn't there been OpenCL implementation somewhere? What supported hardware devices ffmpeg reports if you use this command? ./ffmpeg -help encoder=hevc_amf
Here is beginning of my output, for example:
Encoder hevc_amf [AMD AMF HEVC encoder]:
General capabilities: dr1 delay hardware
Threading capabilities: none
Supported hardware devices: d3d11va d3d11va dxva2 dxva2
Supported pixel formats: nv12 yuv420p d3d11 dxva2_vld p010le
But there potentially may be issues with either AMF or ffmpeg implementation, besides Linux AMD/MESA driver?
P.S. And ffmpeg VBR behaves differently from VCEEnc...
There seems to be some sources, when ffmpeg lays a big dump over target bitrate (it also messes up some mediainfo in output file for some reason). And others, when it does not do that.
(Ah, i see... ffmpeg messes up mediadata and includes audio bitrate in video stream bitrate data)
Like this (ffmpeg output is on the left):
But this is unrelatred to current topic. Just an observation.
Maybe some issue with processing with Vulkan acceleration? Hadn't there been OpenCL implementation somewhere? What supported hardware devices ffmpeg reports if you use this command?
No let's not. It would clutter the bug report even more if we add in other hardware encode variants. I'm gonna stick to just hevc_amf!
It has these options:
Encoder hevc_amf [AMD AMF HEVC encoder]:
General capabilities: dr1 delay hardware
Threading capabilities: none
Supported hardware devices: amf amf
Supported pixel formats: nv12 yuv420p p010le amf
hevc_amf AVOptions:
-usage <int> E..V....... Set the encoding usage (from -1 to 5) (default -1)
transcoding 0 E..V....... Generic Transcoding
ultralowlatency 1 E..V....... Ultra low latency usecase
lowlatency 2 E..V....... Low latency usecase
webcam 3 E..V....... Webcam
high_quality 4 E..V....... High quality usecase
lowlatency_high_quality 5 E..V....... Low latency yet high quality usecase
-profile <int> E..V....... Set the profile (from -1 to 2) (default -1)
main 1 E..V.......
main10 2 E..V.......
-profile_tier <int> E..V....... Set the profile tier (default main) (from -1 to 1) (default -1)
main 0 E..V.......
high 1 E..V.......
-level <int> E..V....... Set the encoding level (default auto) (from 0 to 186) (default auto)
auto 0 E..V.......
1.0 30 E..V.......
2.0 60 E..V.......
2.1 63 E..V.......
3.0 90 E..V.......
3.1 93 E..V.......
4.0 120 E..V.......
4.1 123 E..V.......
5.0 150 E..V.......
5.1 153 E..V.......
5.2 156 E..V.......
6.0 180 E..V.......
6.1 183 E..V.......
6.2 186 E..V.......
-quality <int> E..V....... Set the encoding quality preset (from -1 to 10) (default -1)
quality 0 E..V.......
balanced 5 E..V.......
speed 10 E..V.......
-preset <int> E..V....... Set the encoding quality preset (from -1 to 10) (default -1)
quality 0 E..V.......
balanced 5 E..V.......
speed 10 E..V.......
-latency <boolean> E..V....... enables low latency mode (default auto)
-rc <int> E..V....... Set the rate control mode (from -1 to 6) (default -1)
cqp 0 E..V....... Constant Quantization Parameter
cbr 3 E..V....... Constant Bitrate
vbr_peak 2 E..V....... Peak Contrained Variable Bitrate
vbr_latency 1 E..V....... Latency Constrained Variable Bitrate
qvbr 4 E..V....... Quality Variable Bitrate
hqvbr 5 E..V....... High Quality Variable Bitrate
hqcbr 6 E..V....... High Quality Constant Bitrate
-qvbr_quality_level <int> E..V....... Sets the QVBR quality level (from -1 to 51) (default -1)
-header_insertion_mode <int> E..V....... Set header insertion mode (from -1 to 2) (default -1)
none 0 E..V.......
gop 1 E..V.......
idr 2 E..V.......
-async_depth <int> E..V....... Set maximum encoding parallelism. Higher values increase output latency. (from 1 to 16) (default 16)
-high_motion_quality_boost_enable <boolean> E..V....... Enable High motion quality boost mode (default auto)
-gops_per_idr <int> E..V....... GOPs per IDR 0-no IDR will be inserted (from 0 to INT_MAX) (default 1)
-preencode <boolean> E..V....... Enable preencode (default auto)
-vbaq <boolean> E..V....... Enable VBAQ (default auto)
-enforce_hrd <boolean> E..V....... Enforce HRD (default auto)
-filler_data <boolean> E..V....... Filler Data Enable (default auto)
-max_au_size <int> E..V....... Maximum Access Unit Size for rate control (in bits) (from -1 to INT_MAX) (default -1)
-min_qp_i <int> E..V....... min quantization parameter for I-frame (from -1 to 51) (default -1)
-max_qp_i <int> E..V....... max quantization parameter for I-frame (from -1 to 51) (default -1)
-min_qp_p <int> E..V....... min quantization parameter for P-frame (from -1 to 51) (default -1)
-max_qp_p <int> E..V....... max quantization parameter for P-frame (from -1 to 51) (default -1)
-qp_p <int> E..V....... quantization parameter for P-frame (from -1 to 51) (default -1)
-qp_i <int> E..V....... quantization parameter for I-frame (from -1 to 51) (default -1)
-skip_frame <boolean> E..V....... Rate Control Based Frame Skip (default auto)
-me_half_pel <boolean> E..V....... Enable ME Half Pixel (default auto)
-me_quarter_pel <boolean> E..V....... Enable ME Quarter Pixel (default auto)
-forced_idr <boolean> E..V....... Force I frames to be IDR frames (default false)
-aud <boolean> E..V....... Inserts AU Delimiter NAL unit (default auto)
-preanalysis <boolean> E..V....... Enable preanalysis (default auto)
-pa_activity_type <int> E..V....... Set the type of activity analysis (from -1 to 1) (default -1)
y 0 E..V....... activity y
yuv 1 E..V....... activity yuv
-pa_scene_change_detection_enable <boolean> E..V....... Enable scene change detection (default auto)
-pa_scene_change_detection_sensitivity <int> E..V....... Set the sensitivity of scene change detection (from -1 to 2) (default -1)
low 0 E..V....... low scene change dectection sensitivity
medium 1 E..V....... medium scene change dectection sensitivity
high 2 E..V....... high scene change dectection sensitivity
-pa_static_scene_detection_enable <boolean> E..V....... Enable static scene detection (default auto)
-pa_static_scene_detection_sensitivity <int> E..V....... Set the sensitivity of static scene detection (from -1 to 2) (default -1)
low 0 E..V....... low static scene dectection sensitivity
medium 1 E..V....... medium static scene dectection sensitivity
high 2 E..V....... high static scene dectection sensitivity
-pa_initial_qp_after_scene_change <int> E..V....... The QP value that is used immediately after a scene change (from -1 to 51) (default -1)
-pa_max_qp_before_force_skip <int> E..V....... The QP threshold to allow a skip frame (from -1 to 51) (default -1)
-pa_caq_strength <int> E..V....... Content Adaptive Quantization strength (from -1 to 2) (default -1)
low 0 E..V....... low Content Adaptive Quantization strength
medium 1 E..V....... medium Content Adaptive Quantization strength
high 2 E..V....... high Content Adaptive Quantization strength
-pa_frame_sad_enable <boolean> E..V....... Enable Frame SAD algorithm (default auto)
-pa_ltr_enable <boolean> E..V....... Enable long term reference frame management (default auto)
-pa_lookahead_buffer_depth <int> E..V....... Sets the PA lookahead buffer size (from -1 to 41) (default -1)
-pa_paq_mode <int> E..V....... Sets the perceptual adaptive quantization mode (from -1 to 1) (default -1)
none 0 E..V....... no perceptual adaptive quantization
caq 1 E..V....... caq perceptual adaptive quantization
-pa_taq_mode <int> E..V....... Sets the temporal adaptive quantization mode (from -1 to 2) (default -1)
none 0 E..V....... no temporal adaptive quantization
1 1 E..V....... temporal adaptive quantization mode 1
2 2 E..V....... temporal adaptive quantization mode 2
-pa_high_motion_quality_boost_mode <int> E..V....... Sets the PA high motion quality boost mode (from -1 to 1) (default -1)
none 0 E..V....... no high motion quality boost
auto 1 E..V....... auto high motion quality boost
two more encode variants:
LD_LIBRARY_PATH=/home/mark/pkgbuilds/ffmpeg/upstream/build/lib \
./ffmpeg \
-y -i ~/Videos/potw2423a.mov \
-c:v hevc_amf \
-usage high_quality \
-rc vbr_peak \
-pa_taq_mode 1 \
-minrate 20M \
-maxrate 20M \
-bufsize 20M \
-quality quality \
-preset quality \
-preanalysis 0 \
-preencode 0 \
-pix_fmt nv12 \
-b:v 20M \
-f matroska test_vbr_peak_pa1.mkv
This one works, no jittery crap. But... beats the purpose, i "want" to have predictive frames. Again, compression.. etc...
I removed -enforce_hrd 1 -filler_data 1 and disabled -preanalysis 0 and -preencode 0
Flipping back on just preanalysis brings back the jitter.
LD_LIBRARY_PATH=/home/mark/pkgbuilds/ffmpeg/upstream/build/lib \
./ffmpeg \
-y -i ~/Videos/potw2423a.mov \
-c:v hevc_amf \
-usage high_quality \
-rc vbr_peak \
-pa_taq_mode 1 \
-minrate 20M \
-maxrate 20M \
-bufsize 20M \
-quality quality \
-preset quality \
-preanalysis 1 \
-preencode 0 \
-pix_fmt nv12 \
-b:v 20M \
-f matroska test_vbr_peak_pa1.mkv
So by just going the pinpointing route we can say (which i did a dozen messages ago or so.. but now we can confirm it again) that enabling preanalysis breaks the encode. That could still be the ffmpeg specific implementation or it could be in the amf driver itself. I don't know.
Supported hardware devices: amf amf
Interesting... Well, i guess it is Linux stuff? There is no DX11 nor DX9 available... But they should be Vulkan and OpenCL?
No let's not. It would clutter the bug report even more if we add in other hardware encode variants. I'm gonna stick to just hevc_amf!
hevc_amf is codec, what i meant is processing method (similar to how on Windows there is DX11). I remember that AMF devs implemented Vulkan some time ago and before that there was OpenCL. So maybe something is not fully fleshed out?
So by just going the pinpointing route we can say (which i did a dozen messages ago or so.. but now we can confirm it again) that enabling preanalysis breaks the encode. That could still be the ffmpeg specific implementation or it could be in the amf driver itself. I don't know.
Thanks for confirming again. I just wanted to eliminate all secondary variables from equation. [Especially part with conflicting options] So we can run it down to "enabling preanalysis with AMF encode on Linux causes jitter on video stream. Presumably by placing some frames in incorrect order."
Well, you can try checking not ffmpeg direct AMF encoder. VCEEnc does have .deb and .rpm packages available. https://github.com/rigaya/VCEEnc/releases It still uses ffmpeg components, but it has own interaction with AMF (ffmpeg is used for decoding and filters mostly) If it also have same issue, then problem is most likely to be on either AMF or driver side. [And it also has own debug log functionality, maybe it will help?]
You also can try checking AVC and AV1 encodes, in case if they also output jittery video stream. Purely from data gathering standpoint. (Aka if issue is global, or specific to HEVC)
Interesting... Well, i guess it is Linux stuff? There is no DX11 nor DX9 available... But they should be Vulkan and OpenCL?
Don't know.
hevc_amf is codec, what i meant is processing method (similar to how on Windows there is DX11). I remember that AMF devs implemented Vulkan some time ago and before that there was OpenCL. So maybe something is not fully fleshed out?
That's different pixel surface formats. Regardless, no, not going to play with more variables.
Well, you can try checking not ffmpeg direct AMF encoder. VCEEnc does have .deb and .rpm packages available. https://github.com/rigaya/VCEEnc/releases It still uses ffmpeg components, but it has own interaction with AMF (ffmpeg is used for decoding and filters mostly) If it also have same issue, then problem is most likely to be on either AMF or driver side.
And that's a no again, we're on a roll :) I don't want to add more variables or make it more complex then it already is. Adding another tool for testing really does put in a "unpaid amd dev" testing role.. At some point it's debugged far enough, i think we're at that point now.
You also can try checking AVC and AV1 encodes, in case if they also output jittery video stream. Purely from data gathering standpoint. (Aka if issue is global, or specific to HEVC)
Hard no, sorry. My case is hevc and only because the device i play my video on - AMD too - doesn't have AV1 hardware decoding. Regardless of that little tidbit, HEVC and AV1 really are about the same in terms of quality and size. AV1 is just the free open codec whereas hevc is a licence. For me that difference is irrelevant thus i pick what works which is hevc.
I think we can draw some summarized conclusions (just helping you AMD folks here @Feng-AMD, @MikhailAMD)
- First the quality encode levels (QVBR,HQVBR,HQCBR). Two problems: 1.1 The results @Feng-AMD showed (it adhered to bitrate for him, it did not for me) is inconsistent with with what i showed. This is a bug. 1.2 The documentation is woefully inadequate. It currently is so ambiguous (both open to interpretation and contradicting itself, i showed that example a dozen posts back or so). It might as well not exist at all as this isn't helpful. Sure, this opinion might be a little bit of an exaggeration. 1.3 I like to emphasis that passing values into AMF should always be followed by AMF and you should be really clear to the user when a setting is not accepted/ignored/overwritten. In my examples i passed in specific bitrates just for them to be totally ignored. What else that i pass in is ignored? You should tell this, on the command line, even in release mode like other codecs do too! Perhaps also with warning messages for explicitly telling the user but just giving a summary of the encode settings is in my opinion a mandatory step. This is with the assumption of the default loglevel. Again, follow what others do.
- Planet jitter in examle video. If preanalysis is enabled it ruins the encode on linux. Given that i also saw AMF crashes (sometimes it crashes, sometimes it doesn't, go figure.., the jitter happens in either case) i'm thinking the most likely cause of this bug is the AMF implementation in ffmpeg. It could be a driver bug. Debugging this further really seems like it should be done by AMD, not by me. So i happily hand this one back to you ^_^
I think next steps are up to AMD now. I'll happily try things out in ffmpeg (even apply patches if you have them) but i'm sticking to just that tool to not add more variables in the mix.