obs-studio icon indicating copy to clipboard operation
obs-studio copied to clipboard

obs-ffmpeg: Use Libva to enable FFmpeg VA-API

Open tytan652 opened this issue 2 years ago • 17 comments

Testers: would please add to your feedback the output of the vainfo --all command and if issues a log of OBS with --verbose for debug log.

Description

Fixes #3184

With this change obs-ffmpeg is directly linked to Libva.

Only DRI device with H264 encode endpoint will be shown. If none of them have it, the encoder is not registered.

Also only compatible rate control are shown.

My Nvidia driver only have decoding implemented through VA-API driver.

Before on 27.2.4: VAAPI-1 The VAAPI Codec was removed on master with #6590.

After on master with this PR: VAAPI-2

If the environment variable LIBVA_DRIVER_NAME is set, a warning will be logged. This variable is usually set by advanced user.

if set it could load the wrong driver on the DRI device.

If set to nvidia on my machine:

warning: LIBVA_DRIVER_NAME variable is set, this could prevent FFMPEG VAAPI from working correctly
info: VAAPI: API version 1.15
debug: VAAPI: 'VA-API NVDEC driver' in use for device '/dev/dri/renderD128'
debug: VAAPI: 'VA-API NVDEC driver' in use for device '/dev/dri/renderD129'
info: FFMPEG VAAPI H264 encoding not supported

If not set (the libva error is normal):

info: VAAPI: API version 1.15
debug: VAAPI: 'VA-API NVDEC driver' in use for device '/dev/dri/renderD128'
libva error: /usr/lib/dri/iHD_drv_video.so init failed
debug: VAAPI: 'Intel i965 driver for Intel(R) Haswell Desktop - 2.4.1' in use for device '/dev/dri/renderD129'
info: FFMPEG VAAPI H264 encoding supported

If set with iHD:

warning: LIBVA_DRIVER_NAME variable is set, this could prevent FFMPEG VAAPI from working correctly
DRM_IOCTL_I915_GEM_APERTURE failed: Invalid argument
Assuming 131072kB available aperture size.
May lead to reduced performance or incorrect rendering.
get chip id failed: -1 [22]
param: 4, val: 0
libva error: /usr/lib/dri/iHD_drv_video.so init failed
error: VAAPI: Fail to initialise
libva error: /usr/lib/dri/iHD_drv_video.so init failed
error: VAAPI: Fail to initialise
info: FFMPEG VAAPI H264 encoding not supported

Motivation and Context

Non-compatible DRI device should not be shown.

How Has This Been Tested?

Without the change, the encoder show my Nvdia card.

With it, it does not.

And with LIBVA_DRIVER_NAME set to a wrong driver to simulate no H264 endpoint, the encoder is not registered.

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist:

  • [x] My code has been run through clang-format.
  • [x] I have read the contributing document.
  • [x] My code is not on the master branch.
  • [x] The code has been tested.
  • [x] All commit messages are properly formatted and commits squashed where appropriate.
  • [x] I have included updates to all appropriate documentation.

tytan652 avatar Jul 01 '22 18:07 tytan652

This doesn't seem to work as intended on my Intel NUC.

Intel Core i7-10710U CPU @ 1.10GHz
Loading up OpenGL on adapter Intel Mesa Intel(R) UHD Graphics (CML GT2)
OpenGL loaded successfully, version 4.6 (Core Profile) Mesa 22.0.1, shading language 4.60

Here's how it works on latest master (driver only supports CQP, but it works). 2022-07-02 12-19-51.txt

And this is with this PR. Notice that it logs FFMPEG VAAPI H264 encoding not supported. UI doesn't list VAAPI at all. 2022-07-02 12-18-01.txt

WizardCM avatar Jul 02 '22 02:07 WizardCM

I need to cover more profile while testing, I thought that checking for H264 Constrained Baseline (non-LP) was enough.

Can I have the output of the vainfo --all command to see each profile and entrypoint with their compatible control rate of your iGPU.

tytan652 avatar Jul 02 '22 04:07 tytan652

I need to cover more profile while testing, I thought that checking for H264 Constrained Baseline was enough.

Can I have the output of the vainfo --all command to see each profile and endpoint with their compatible control rate of your iGPU.

vainfo.txt

WizardCM avatar Jul 02 '22 04:07 WizardCM

  • Low power entrypoints are now allowed.
  • Only compatible rate control are shown.
  • Defaults is adapted against the first supported device.

Edit: The next push will just be reword of the commit

tytan652 avatar Jul 02 '22 09:07 tytan652

log_cookie.txt vainfo_cookie.txt

Here ya go, log&vainfo.

thecookie94 avatar Jul 02 '22 13:07 thecookie94

On my side, the patch work. I can see my vaapi device normal.

As a addition, my vainfo:

vainfo: VA-API version: 1.14 (libva 2.14.0)
vainfo: Driver version: Mesa Gallium driver 22.1.2 for AMD Radeon RX 5500 XT (navi14, LLVM 13.0.1, DRM 3.44, 5.17.15-1-MANJARO)
vainfo: Supported config attributes per profile/entrypoint pair
VAProfileMPEG2Simple/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileMPEG2Main/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileVC1Simple/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileVC1Main/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileVC1Advanced/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileH264ConstrainedBaseline/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileH264ConstrainedBaseline/VAEntrypointEncSlice
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
    VAConfigAttribRateControl              : VA_RC_CBR
                                             VA_RC_VBR
                                             VA_RC_CQP
    VAConfigAttribEncPackedHeaders         : VA_ENC_PACKED_HEADER_NONE
    VAConfigAttribEncMaxRefFrames          : l0=1
                                             l1=0
    VAConfigAttribEncRateControlExt        : max_num_temporal_layers_minus1=3 temporal_layer_bitrate_control_flag=1

VAProfileH264Main/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileH264Main/VAEntrypointEncSlice
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
    VAConfigAttribRateControl              : VA_RC_CBR
                                             VA_RC_VBR
                                             VA_RC_CQP
    VAConfigAttribEncPackedHeaders         : VA_ENC_PACKED_HEADER_NONE
    VAConfigAttribEncMaxRefFrames          : l0=1
                                             l1=0
    VAConfigAttribEncRateControlExt        : max_num_temporal_layers_minus1=3 temporal_layer_bitrate_control_flag=1

VAProfileH264High/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileH264High/VAEntrypointEncSlice
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
    VAConfigAttribRateControl              : VA_RC_CBR
                                             VA_RC_VBR
                                             VA_RC_CQP
    VAConfigAttribEncPackedHeaders         : VA_ENC_PACKED_HEADER_NONE
    VAConfigAttribEncMaxRefFrames          : l0=1
                                             l1=0
    VAConfigAttribEncRateControlExt        : max_num_temporal_layers_minus1=3 temporal_layer_bitrate_control_flag=1

VAProfileHEVCMain/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileHEVCMain/VAEntrypointEncSlice
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
    VAConfigAttribRateControl              : VA_RC_CBR
                                             VA_RC_VBR
                                             VA_RC_CQP
    VAConfigAttribEncPackedHeaders         : VA_ENC_PACKED_HEADER_SEQUENCE
    VAConfigAttribEncMaxRefFrames          : l0=1
                                             l1=0

VAProfileHEVCMain10/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422
                                             VA_RT_FORMAT_YUV420_10
                                             VA_RT_FORMAT_YUV420_10BPP

VAProfileHEVCMain10/VAEntrypointEncSlice
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV420_10
                                             VA_RT_FORMAT_YUV420_10BPP
    VAConfigAttribRateControl              : VA_RC_CBR
                                             VA_RC_VBR
                                             VA_RC_CQP
    VAConfigAttribEncPackedHeaders         : VA_ENC_PACKED_HEADER_SEQUENCE
    VAConfigAttribEncMaxRefFrames          : l0=1
                                             l1=0

VAProfileJPEGBaseline/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileVP9Profile0/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422

VAProfileVP9Profile2/VAEntrypointVLD
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV422
                                             VA_RT_FORMAT_YUV420_10
                                             VA_RT_FORMAT_YUV420_10BPP

VAProfileNone/VAEntrypointVideoProc
    VAConfigAttribRTFormat                 : VA_RT_FORMAT_YUV420
                                             VA_RT_FORMAT_YUV420_10
                                             VA_RT_FORMAT_RGB32
                                             VA_RT_FORMAT_YUV420_10BPP

tiberium-v avatar Jul 02 '22 14:07 tiberium-v

~~@WizardCM since you have a Intel iGPU, I need a verbose log made with this PR Flatpak. This is to check if I'm not the only one not having the Intel VAAPI extension enabled on the Flatpak.~~

~~flatpak run com.obsproject.Studio --branch=master --command="obs --verbose"~~

LIBVA_DRIVER_NAME was transferred to the Flatpak env causing an issue.

tytan652 avatar Jul 02 '22 16:07 tytan652

Now callback are set to use blog rather than Libva original method to log message. And so those message are also added to OBS log.

Example:

info: VA-API: API version 1.15
debug: VA-API: 'VA-API NVDEC driver' in use for device '/dev/dri/renderD128'
libva error: /usr/lib/dri/iHD_drv_video.so init failed
debug: VA-API: 'Intel i965 driver for Intel(R) Haswell Desktop - 2.4.1' in use for device '/dev/dri/renderD129'
info: FFmpeg VA-API H264 encoding supported

Become:

info: VA-API: API version 1.15
debug: VA-API: 'VA-API NVDEC driver' in use for device '/dev/dri/renderD128'
debug: Libva error: /usr/lib/dri/iHD_drv_video.so init failed
debug: VA-API: 'Intel i965 driver for Intel(R) Haswell Desktop - 2.4.1' in use for device '/dev/dri/renderD129'
info: FFmpeg VA-API H264 encoding supported

tytan652 avatar Jul 02 '22 20:07 tytan652

Just removed unused variable that I forgot to remove.

tytan652 avatar Jul 09 '22 07:07 tytan652

~~Made the encoder fail if CBR is enforced and not supported by the device.~~

~~Need reviews about this decision/change.~~

tytan652 avatar Jul 11 '22 18:07 tytan652

Made the encoder fail if CBR is enforced and not supported by the device.

Need reviews about this decision/change.

I don't know, if that help you by testing on a device that allowed it. But when it is relevant: It didn't break on my side. I can use it with CBR as intended.

tiberium-v avatar Jul 11 '22 19:07 tiberium-v

@WizardCM I need to know how the encoder actually (without the PR) behave with devices that does not support CBR with OBS that enforce it with services (error dialog, crash, error logs).

In the last UI/UX call, my last changes was debated and the decision to remove it for now (if it make the situation worse) was taken.

Edit: removed to make it mergeable as it is.

tytan652 avatar Jul 11 '22 21:07 tytan652

Strings fixed.

tytan652 avatar Jul 21 '22 05:07 tytan652

I've retested this, and the UI now correctly names my integrated GPU and correctly hides unsupported modes.

image

However it seems that in a profile I previously used now shows "No properties available" for a pre-configured streaming profile. Switching to x264 and back does restore the properties. Additionally, the other 3 Profiles I have configured with VAAPI don't have this issue. It could be an edge case.

image

It does look like all VAAPI configs that previously had non-CQP rate controls enabled are now visually set to CQP in the UI,


Separately, if an invalid GPU is selected somehow (unsure how, likely from a previous iteration of this PR), then attempting to go live will fail.

error: VAAPI: Failed to open device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: VAAPI: Failed to query profiles from device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: VAAPI: Failed to open device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: VAAPI: Failed to query profiles from device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: VAAPI: Failed to open device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: VAAPI: Failed to query profiles from device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: VAAPI: Failed to open device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: VAAPI: Failed to query profiles from device '/dev/dri/by-path/pci-0000:09:00.0-render'
info: ---------------------------------
info: [FFmpeg VAAPI encoder: 'advanced_video_recording'] settings:
	device:       /dev/dri/by-path/pci-0000:09:00.0-render
	rate_control: CQP
	profile:      578
	level:        40
	qp:           16
	bitrate:      0
	maxrate:      0
	keyint:       120
	width:        1920
	height:       1080
	b-frames:     0

[AVHWDeviceContext @ 0x556c9969ac00] No VA display found for device /dev/dri/by-path/pci-0000:09:00.0-render.
warning: [FFmpeg VAAPI encoder: 'advanced_video_recording'] Failed to create VAAPI device context: Invalid argument

Then, attempting to change the device and rate control to the same element in the dropdown will cause an immediate crash.

error: VAAPI: Failed to open device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: VAAPI: Failed to query profiles from device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: VAAPI: Failed to open device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: VAAPI: Failed to query profiles from device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: VAAPI: Failed to open device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: VAAPI: Failed to query profiles from device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: VAAPI: Failed to open device '/dev/dri/by-path/pci-0000:09:00.0-render'
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: bmalloc: Allocating 0 bytes is broken behavior, please fix your code! This will crash in future versions of OBS.
error: VAAPI: Failed to query profiles from device '/dev/dri/by-path/pci-0000:09:00.0-render'
info: Settings changed (outputs)
info: ------------------------------------------------
#0 0x7fad01d787b3 <unknown>
#1 0x7fad01e1e6fc <unknown>
#2 0x7fad01e1e5d0 <unknown>
#3 0x7fad01e0f6cd <unknown>
#4 0x7fad01e384ba <unknown>
#5 0x7fad01d8fa88 <unknown>
#6 0x7fad00358738 <unknown>
#7 0x7fad0033399f <unknown>
#8 0x7fad00333693 <unknown>
#9 0x7fad003541bd <unknown>
#10 0x7fad01e37b30 <unknown>
#11 0x7fad01f7c7ad <unknown>
#12 0x7fad01e37e91 <unknown>
#13 0x7fad01ddf7dd <unknown>
#14 0x7fad01db141b <unknown>
#15 0x7fad01df7df8 <unknown>
#16 0x7facffd1a660 <unknown>
#17 0x7fad01df7f82 <unknown>
#18 0x7fad01e1a4ef <unknown>
#19 0x7fad93641b43 <unknown>
Trace/breakpoint trap (core dumped)

Unfortunately the config was saved so the crash is no longer an issue on my setup so I can't get a proper trace.

WizardCM avatar Jul 24 '22 03:07 WizardCM

I need to care about previous version profile, I don't know.

Does the bmalloc warnings appeared because of my PR ?

tytan652 avatar Jul 24 '22 07:07 tytan652

I maybe found the reason of the crash, forgot to close the va display on a callback if the device doesn't support h264.

tytan652 avatar Jul 24 '22 08:07 tytan652

I made a re-work of this, now the VAAPI code is less H264-centric.

tytan652 avatar Aug 30 '22 08:08 tytan652

I tested with Radeon RX 6600 and Intel Core i7-7700 with this PR rebased to the latest master. It looks ok; both Navi 23 and HD Graphics 630 are listed on the output settings. https://obsproject.com/logs/ns3sBPWL9RZUGt2H

norihiro avatar Oct 02 '22 00:10 norihiro

OK, I need to add test for all h264 profile ans control rate then.

tytan652 avatar Oct 11 '22 07:10 tytan652

What is left that we need to test for this one? Can we get a summary of what is left, so that we can get the last bit of testing for this done?

Fenrirthviti avatar Nov 11 '22 21:11 Fenrirthviti

@Fenrirthviti:

  • Not show card that don't support H264 encode was tested on my machine (Desktop with GTX 970 + Intel iGPU).
  • Show only compatible rate control was tested by @WizardCM.
  • I got positive feedback from Denis (Tiberium) and Cookie who are AMD users.

I guess there is nothing left to test as it is.

tytan652 avatar Nov 12 '22 07:11 tytan652

looks good to me, feel free to squash up the changes.

kkartaltepe avatar Nov 14 '22 20:11 kkartaltepe