Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting HW Accel to "nvenc" when using x265 does not set the encoder to "hevc_nvenc" as expected #41

Open
Henri-J-Norden opened this issue Apr 30, 2020 · 12 comments
Labels

Comments

@Henri-J-Norden
Copy link

Hi!
I noticed that with nvenc on x264 I got an encoding framerate >100fps, while with x265 the performance was an abysmal ~15 fps.

The issue: on x264 with HW Accel set to nvenc, the program properly sets the encoder to h264_nvenc, while on x265 the encoder is always set to libx265. I verified this by manually changing the encoder in the generated script to hevc_nvenc and this resulted in good encoding performance similar to x264 with nvenc enabled. Hopefully this is an easy fix.

I am using version 1.7.9.1-Alpha.

Best regards,
Henri

@MattMcManis MattMcManis added the bug label May 6, 2020
@MattMcManis
Copy link
Owner

Thanks for finding this bug, it was a typo in the code, causing it to skip x265.

I've released an update.

Press the arrow button in Axiom to update through PowerShell, or download from here
https://github.com/MattMcManis/Axiom/releases

Update

@VA1DER
Copy link

VA1DER commented May 10, 2020

There is still a bug. The "fix" sets the encoder as "x265_nvenc", but for x265 the codec should be set to "hevc_nvenc".

@MattMcManis
Copy link
Owner

MattMcManis commented May 11, 2020

@VA1DER

I see, the HWAccel section had a some other problems with it. I've released an update.

cuvid
x264 is -c:v h264_cuvid
x265 is -c:v hevc_cuvid

nvenc
x264 is -c:v h264_nvenc
x265 is -c:v hevc_nvenc

cuvid+nvenc
x264 is -hwaccel cuvid -c:v h264_nvenc
x265 is -hwaccel cuvid -c:v hevc_nvenc

@VA1DER
Copy link

VA1DER commented May 12, 2020

There is still an issue with cuvid and cuvid+nvenc. Neither produce proper command lines for me.

Cuvid is a decode-only acceleration, so -c:v hevc_cuvid has to appear before the input file. The output codec should be just the non-accelerated libx265, for example.

Cuvid+NVENC - is this even a legal usage? I can't get it to work with any command line in my FFMPEG.

@MattMcManis
Copy link
Owner

I'll fix cuvid, and might remove cuvid+nvenc, and add these new options #42 (comment) I'll release an update soon.

@MattMcManis
Copy link
Owner

MattMcManis commented May 12, 2020

@VA1DER

Does this look correct?

dxva2 (decode)

ffmpeg -hwaccel dxva2 -i input.mpg -c:v libx264 output.mp4

cuda (decode)

ffmpeg -hwaccel cuda -i input.mpg -c:v libx264 output.mp4

cuvid (decode)

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input.mpg output.mp4

or

ffmpeg -hwaccel cuvid -i input.mpg -c:v libx264 output.mp4

nvenc (transcode)

ffmpeg -i input.mpg -c:v h264_nvenc output.mp4

nvenc+cuda (transcode)

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mpg -c:v h264_nvenc output.mp4

qsv (transcode)

ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -i input.mpg -c:v h264_qsv output.mp4

Resources:
https://trac.ffmpeg.org/wiki/HWAccelIntro
https://trac.ffmpeg.org/wiki/Hardware/QuickSync

@MattMcManis
Copy link
Owner

@VA1DER

I redid a lot of the code for HW Accel. I released the update for you to test.

CUVID still might not work properly, I don't have the custom compiled ffmpeg to test it.

Intel QSV hevc_qsv gives loading plugin error, but h264_qsv works.

@VA1DER
Copy link

VA1DER commented May 12, 2020

@MattMcManis

The Zeranoe ffmpeg builds (I use the static ones) have all the hardware support built in.

CUVID Decode: Omit the "-hwaccel cuvid". With CUVID you just need to know the input codec and to speciffy the correct cuvid decoder on the command line.
ffmpeg -c:v h264_cuvid -i input.mp4 -c:v (outputcodec) output.mp4

It's kind of dumb, actually. In fact the whole hardware accel command line system in ffmpeg is dumb in that different types of acceleration use completely different command line paradigms.
dxva2 is correct. nvenc is correct. qsv is correct.

I was mistaken about cuvid+nvenc not being legal. It works. In fact, I can make a command line that works for all the decode-only hardware accelerations and also works with nvenc encoding acceleration:

cuvid+nvenc
ffmpeg -c:v h264_cuvid -i input.mkv -c:v hevc_nvenc output.mp4

dxva2+nvenc
ffmpeg -hwaccel dxva2 -i input.mkv -c:v hevc_nvenc output.mp4

I cannot figure out a way to get qsv and nvenc to work together.

I would suggest if you want to support decode-only accel that you split up the decode hardware accel and the encode hardware accel into two settings. There might have to be some glue logic to forbid combinations that don't work.

@VA1DER
Copy link

VA1DER commented May 12, 2020

@MattMcManis

For what it's worth, I put in an enhancement ticket with ffmpeg to clean up their command line:

https://trac.ffmpeg.org/ticket/8666#ticket

I don't hold out much hope, but we'll see.

@MattMcManis
Copy link
Owner

MattMcManis commented May 13, 2020

@VA1DER

When trying to use NVENC, I get the error Cannot load nvEncodeAPI64.dll. Maybe my graphics card does not have the driver that supports it.

I might remove CUVID, since there is no easy way for the user to know the input codec.


How does this look for splitting HW Accel options into 2 parts?
Or I could have 1 menu with individual and all combinations.

Decode

  • CUDA
  • D3D11VA
  • DXVA2
  • Intel QSV

Transcode

  • NVENC
  • Intel QSV

Combinations

  • D3D11VA+NVENC
  • D3D11VA+Intel QSV
  • DXVA2+NVENC
  • DXVA2+Intel QSV
  • CUDA+NVENC
  • CUDA+Intel QSV
  • Intel QSV+Intel QSV

@MattMcManis
Copy link
Owner

@VA1DER

I've released an update with some new options:

  • HW Accel Decode and Transcode menus.
  • HW Accel Decode option auto.
  • HW Accel Transcode option AMD AMF for x264/x265.
  • Video Tab has new Sub Tabs, Encoding, Color, Size, to reduce the vertical scrolling height.

These changes could introduce new bugs, you will have to test it out and let me know how it works. Certain HW Accel options may need the required Intel/Nvidia/AMD hardware.
Some HW Accel Transcode codecs are only available for x264/x265.

https://github.com/MattMcManis/Axiom/releases

See a related issue here #42 (comment)

@MarcoRavich
Copy link

Just found this interesting insight @ StackExchange:

Notes on encoding with the QSV encoders:
Typically, you will need to initialize a hardware device that will be used by both the encoder(s) in use and filtering, as shown in the example below:

ffmpeg -y -loglevel debug -init_hw_device qsv=hw -filter_hw_device hw -hwaccel qsv -hwaccel_output_format qsv \
-i simpsons.mp4 -vf 'format=qsv,hwupload=extra_hw_frames=64'  \
-c:v hevc_qsv \
-bf 3 -b:v 3.75M -maxrate:v 3.75M -bufsize:v 0.5M -r:v 30 -c:a copy -f mp4 trolled.mp4

See how the hardware device for use with MFX sessions has been initialized (-init_hw_device qsv=hw) and mapped as available to filters such as hwupload (-filter_hw_device hw).

Recommended for further reading: The Advanced Video options section on FFmpeg wiki.

The example above demonstrates the use of the hevc_qsv encoders with some private options passed to it, for reference.

Another example, showing the use of the h264_qsv encoder:

ffmpeg -y -loglevel debug -init_hw_device qsv=hw -filter_hw_device hw -hwaccel qsv -hwaccel_output_format qsv \
-i simpsons.mp4 -vf 'format=qsv,hwupload=extra_hw_frames=64'  \
-c:v h264_qsv \
-bf 3 -b:v 15M -maxrate:v 15M -bufsize:v 2M -r:v 30 -c:a copy -f mp4 trolled.mp4

Take note that both examples above will use the constant bitrate control (CBR) method in MFX, as shown in the console log:
[hevc_qsv @ 0x55faf21eedc0] Using the constant bitrate (CBR) ratecontrol method

Rate control, similar to how the VAAPI implementation governs it, is driven by the parameters -b:v (target video bitrate) and the -maxrate:v (maximum video bitrate) passed to the encoder. If they are equal, CBR (constant bitrate control) is used. If maxrate is greater than target bitrate, then VBR, and in effect, look-ahead based control (if so desired) are enabled.

Observe how we call up the hwupload filter, chained with the format=qsv filter to ensure that the MFX runtime receives a supported pixel format. Failure to pass this video filter chain will result in initialization failure, with output similar to this:

[h264_qsv @ 0x560e1bda7280] Selected ratecontrol mode is unsupported
[h264_qsv @ 0x560e1bda7280] Low power mode is unsupported
[h264_qsv @ 0x560e1bda7280] Current frame rate is unsupported
[h264_qsv @ 0x560e1bda7280] Current picture structure is unsupported
[h264_qsv @ 0x560e1bda7280] Current resolution is unsupported
[h264_qsv @ 0x560e1bda7280] Current pixel format is unsupported
[h264_qsv @ 0x560e1bda7280] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters.
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

The error message may seem ambiguous at first, but it stems primarily from mapping invalid options to the underlying MFX library, such as an unsupported pixel format.

The extra argument extra_hw_frames=64 passed to hwupload has to do with the MFX runtime requiring a fixed frame pool size to be pre-allocated. Use a number suitable to your requirements. Generally, you'll need a larger number (64, or thereabouts) if using features such as look-ahead (LA-ICQ).

Hope that helps/inspires !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants