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

[Bug Report] Intel QuickSync not working #5069

Closed
gitgiggety opened this issue Jul 13, 2024 · 6 comments · Fixed by #5154
Closed

[Bug Report] Intel QuickSync not working #5069

gitgiggety opened this issue Jul 13, 2024 · 6 comments · Fixed by #5154
Labels
bug report Bug reports that are not yet verified

Comments

@gitgiggety
Copy link
Contributor

Describe the bug
For me Intel QuickSync support is not working on an Intel N5105 based system. QSV is tested for / used with a combination of options which is not compatible with at least Jasper Lake CPUs. This is due to -global_quality being used which leads to a ratecontrol as described here: https://ffmpeg.org/ffmpeg-codecs.html#Ratecontrol-Method This while Jasper Lake CPUs are limited in functionality and seemingly only supports some of those ratecontrol methods.

To Reproduce
Steps to reproduce the behavior:

  1. Install Stash on a system with a Jasper Lake CPU like an N5105
  2. Enable "FFmpeg hardware encoding"
  3. Restart

Expected behavior
Startup log message shows that h264_qsv is supported. But instead is just:

[InitHWSupport] Supported HW codecs [2]:
h264_vaapi
vp9_vaapi

While this could/should include h264_qsv and possibly vp9_qsv.

Screenshots

Stash Version: (from Settings -> About):
0.26.2

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context
Trace logs of startup:

[InitHWSupport] Codec h264_qsv not supported. Error output:[h264_qsv @ 0x7fecc212dc00] Error initializing the encoder: invalid video parameters (-15)
[vost#0:0/h264_qsv @ 0x7fecc2ac7540] Error while opening encoder - maybe incorrect parameters such as bit_rate, rate, width or height.
Error while filtering: Invalid argument
[out#0/null @ 0x7fecc2ae5280] Nothing was written into output file, because at least one of its streams received no packets.

Used ffmpeg flags to check QSV support:

-hide_banner -v warning -init_hw_device qsv=hw -filter_hw_device hw -f lavfi -i color=c=red:s=1280x720 -t 0.1 -c:v h264_qsv -global_quality 20 -preset faster -vf hwupload=extra_hw_frames=64,format=qsv,scale_qsv=-1:256 -f null -

Execting ffmpeg with the same flags, except dropping global_quality 20 executes succesfully.

Note:
I haven't tested if there are any other issues yet, but transcoding a 4K video to 1280x720 with a basic command like:

ffmpeg -hwaccel qsv -c:v h264_qsv -i input.mp4 -vf scale_qsv=w=1280:h=720 -c:v h264_qsv output.mp4

Does show a speed of ~1.75x, and the CPU not being stressed and intel_gpu_top showing that the GPU is fully used (100% "busy" in the "video" engine). While without qsv the CPU maxes all cores at 100% and the speed is below 1 (so playback actually having to wait for the next pieces to be finished).
(But I didn't finish a file and play it back, but I presume it should be working just fine, albeit maybe in a bit lower quality than what it would be if those ratecontrol methods were supported).

@gitgiggety gitgiggety added the bug report Bug reports that are not yet verified label Jul 13, 2024
@gitgiggety
Copy link
Contributor Author

I have created a small Python script which I configured as FFmpeg path in Stash. This script takes the original arguments but removes the -global_quality option from it. And with this video transcoding does work fine using QSV hardware transcoding.

This is the script:

#!/usr/bin/python

import os
import sys

args=["/usr/bin/ffmpeg"]
i=1
while i < len(sys.argv):
    if sys.argv[i] == "-global_quality":
        i += 2
    else:
        args.append(sys.argv[i])
        i += 1

os.execv(args[0], args)

@gitgiggety
Copy link
Contributor Author

gitgiggety commented Jul 13, 2024

The above actually yields a terrible result / quality. This (probably) as no quality is defined. Using -q instead of -global_quality fixes this. So the wrapper then becomes:

#!/usr/bin/python

import os
import sys

args=["/usr/bin/ffmpeg"]
i=1
while i < len(sys.argv):
    if sys.argv[i] == "-global_quality":
        args.append("-q")
        i += 1
    else:
        args.append(sys.argv[i])
        i += 1

os.execv(args[0], args)

Setting a bitrate using -b:v and/or -maxrate can also be done, but will most likely depend on the chosen resolution etc. I.e.: both set to 5M was fine when testing on 1280x720 and looks to equal -q 20, but will probably be (to) low for 1920x1080 or 4K.

And when testing with a 4K video downscaled to 1280x720 the results of both -q 20 and -b:v 5M -maxrate 5M are of a better quality than software encoding (while without these the quality is way worse than software encoding).

@NodudeWasTaken
Copy link
Contributor

Using -q or -qscale is constant quantization which is generally a bad idea for encoding and we shouldn't default to it (even if we use it on vaapi for the lack of a better option).
We should however introduce more customization for each encoder.

@gitgiggety
Copy link
Contributor Author

@NodudeWasTaken yeah sure. My intention wasn't to push for changing -global_quality to -q. I don't know enough (or actually nothing at all) about this stuff and what the consequences would be of such a change (in performance, quality, needed bitrate / bandwidth, ...).

So just reporting the issue, combined with a command which at least does work, and a work-a-round for others which have the same issue.

Regarding "introduce more customization for each encoder", I'm not sure if that would be the right path. I can imagine that would become hugely complex and overwelming, while there already are settings to add "input" and "output" flags to ffmpeg commands which users already can use to fine tune the transcoding. And in this specific case it ideally should "just work". Possibly by expanding the implemented encoders with a new one for this scenario. So run a test with QSV + -global_quality and a test with QSV + -q. Which will result in either both or only the last succeeding / being possible. And I assume there is already a "priority" implemented for all supported encoders which in this case should prioratize the -global_quality one.

@Net005
Copy link

Net005 commented Aug 19, 2024

@gitgiggety Tried the Python wrapper as ffmpeg path however it keeps reporting file not found even though it's there:

vivaldi_PdOVAdWtMm

If I add a binary file original ffmpeg as ffmpeg_qsv for testing at same location it works without errors.
Any pointers on how to get this working?

Stash version: v0.26.2-63-ga94bf29b
Running in latest docker container

@gitgiggety
Copy link
Contributor Author

Thanks @NodudeWasTaken, just upgraded to 0.27(.0) and it's working fine now, no hack needed anymore 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report Bug reports that are not yet verified
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants