fzwoch / obs-gstreamer

GStreamer OBS Studio plugin
GNU General Public License v2.0
358 stars 34 forks source link

Option for device selection #79

Closed GloriousEggroll closed 2 years ago

GloriousEggroll commented 2 years ago

Would it be possible to add the option for device select (in case of igpu + dgpu or multiple dgpus)?

From what I was informed gstreamer doesnt have an option that can be set for that, but they do have an envvar:

GST_VAAPI_DRM_DEVICE

I'm wondering if it would be possible to get the device list/ info in the same way that ffmpeg vaapi does, but instead of appending the option as an ffmpeg option, just export the environment variable as soon as they select it from the list and confirm their settings.

fzwoch commented 2 years ago

Possible? Probably. But I don't have plans to do so.

Tbh, this whole encoder part of the plugin was quite quickly written and never intended to be real encoder alternative. It enabled some POC for obscure platforms and it is helpful tinkering with some things. But it will probably never be a decent replacement for what is in OBS.

If there is an issue with VAAPI with the current implementation in FFMPEG or OBS it should get investigated there and fixed.

GloriousEggroll commented 2 years ago

But it will probably never be a decent replacement for what is in OBS.

This is far from true. This implementation is quite easily superior in terms of both performance and quality compared to the ffmpeg vaapi plugin. It has been complained about for years but it is not something that can be addressed from the OBS side -- it's an FFMPEG issue.

Just to put it into perspective -- on my 6900 XT with h264, ffmpeg vaapi overloads my encoder at 1440p. On an RX 580 it overloads a 1080p60. With this plugin on the other hand both of these cards are able to record at the same full resolution potential at 60 fps at great quality without so much as a hiccup on both h264 and 265. I think you're greatly underestimating the performance difference here.

I have literally been struggling with finding a means for a solid 4k60 capture for -years- (yes, including buying the 1k magewell card) only to find out that ffmpeg vaapi cant handle it, hell not even AMD's own AMF encoder can handle it, but this thing just cruises like its nothing. I'm baffled really.

FWIW -- I am the one who pushed the original ffmpeg vaapi plugin into obs:

https://github.com/obsproject/obs-studio/commit/a64ae11bce8ed9a7c8f1deba3338f77595dba903

and I simply do not have the brains to make it work any better than it currently does -- which is -NOT- as good as yours.

fzwoch commented 2 years ago

I see. I did try with latest FFMPEG VAAPI and ended up with about 11ms processing time for 1080p, so I thought things would not be not looking too bad.

If it makes such a difference maybe it should be a standalone plugin. I just feel horrible changing the existing codebase here really. Maybe even operating with VA API directly instead of GStreamer?

GloriousEggroll commented 2 years ago

I see. I did try with latest FFMPEG VAAPI and ended up with about 11ms processing time for 1080p, so I thought things would not be not looking too bad.

If it makes such a difference maybe it should be a standalone plugin. I just feel horrible changing the existing codebase here really. Maybe even operating with VA API directly instead of GStreamer?

I will tell you if you do a quick search for FFMPEG VAAPI almost -everyone- on an AMD card is using depackaged and repackaged amd AMF proprietary drivers + StreamFX plugin for encoding using the proprietary driver, and the opinion of VAAPI's performance for anything lower than navi is -- well it sucks. Your solution provides an -excellent- out of the box obs experience without people having to go around their butt to get to their elbow. It's worth the swap and I really feel the main thing missing here is just the ability to choose which GPU. As for interfacing with vaapi directly.. I have no idea how to do that and I don't think aiming to reinvent the wheel a 3rd time is going to do us any favors.

Big-FG commented 2 years ago

This is far from true. This implementation is quite easily superior in terms of both performance and quality compared to the ffmpeg vaapi plugin. It has been complained about for years but it is not something that can be addressed from the OBS side -- it's an FFMPEG issue.

Just to chime in here, Im no expert in the matter but from my testing also this is very much the case. This plugin slaps every other option for easy of use or performance/quality.

Right now on an RX480 while the output for 720p is a bit softer than id prefer its leaps beyond FFMPEG VAAPI built into OBS which is a blocky mess/ performance sucks and while i cant test AMF due to being on silverblue and doing flatpak OBS it comes close to previous testing ive done with AMF on Arch and I havent run into any performance issues with encoding with this plugin. Ill give Recording/Streaming at the same time a try later.

This has easily become my favorite and most necessary plugin as i had lost hope for anything to happen in OBS as they dont want HEVC or H265 which is the other best option on AMD. This solves a years old issue of Hardware Encoding with AMD in OBS.

fzwoch commented 2 years ago

So the above branch may implement the option to switch devices. I cannot test it as I don't have such a setup - but at least I could make it not work by setting an invalid device manually. So it does do something at least..

RushingAlien commented 2 years ago

Gitlab:[Feature][Gstreamer VA-API] API for VA-API DRM device selection for use by apps. a gstreamer maintainer showed interest on an API for selecting device :)

GloriousEggroll commented 2 years ago

So the above branch may implement the option to switch devices. I cannot test it as I don't have such a setup - but at least I could make it not work by setting an invalid device manually. So it does do something at least..

Sure I can give this a test tonight, will report back soon

GloriousEggroll commented 2 years ago

It's working great. Here's how I tested for confirmation:

System had both an RX 6700 XT and an RX 5500 in it They came up as /dev/dri/renderD128 and /dev/dri/renderD129

I went to /dev/dri/ and set chmod 600 on /dev/dri/renderD129

then went to OBS, tried renderD128 -- worked fine. Tried renderD129 -- hit play button, it acts like its recording but its not outputting any file. I hit stop recording and it hangs instead of properly stopping and spitting out a video.

change the permissions back -- everything is peachy.

Some notes:

Noticed the device chooser currently only shows up for h.264,not 265. guessing that was intentional for POC Noticed x264 still remains an option when a device is selected, probably needs to be removed if selecting a gpu device to render to.

RushingAlien commented 2 years ago

Nice, tho just wanna add in this comment from a gstreamer maintainer Víctor Manuel Jáquez Leal @vjaquez comments :

Agreed, the environment variable is an horrible hack. The correct approach for device selection is through GstContext by the application: the application creates a GstContext which is passed to the pipeline when a vaapi element request it. If the application doesn't provided, it creates one (with all the assumptions) and share it among the pipelines for other possible vaapi elements that request it. Saddly, the bolts for handling a drm fd context are not placed (only for X11 and Wayland) -- if I recall correctly. Bear in mind that we're working in the new encoders for va plugin, where drm device api is through the element names, as in v4l2 elements, with implicit discoverability.

not sure what to take from this,not well versed in gstreamer lingo

GloriousEggroll commented 2 years ago

Nice, tho just wanna add in this comment from a gstreamer maintainer Víctor Manuel Jáquez Leal @vjaquez comments :

Agreed, the environment variable is an horrible hack. The correct approach for device selection is through GstContext by the application: the application creates a GstContext which is passed to the pipeline when a vaapi element request it. If the application doesn't provided, it creates one (with all the assumptions) and share it among the pipelines for other possible vaapi elements that request it. Saddly, the bolts for handling a drm fd context are not placed (only for X11 and Wayland) -- if I recall correctly. Bear in mind that we're working in the new encoders for va plugin, where drm device api is through the element names, as in v4l2 elements, with implicit discoverability.

not sure what to take from this,not well versed in gstreamer lingo

the short of it is in order for proper implementation to happen :

The correct approach for device selection is through GstContext by the application: the application creates a GstContext which is passed to the pipeline when a vaapi element request it. If the application doesn't provided, it creates one (with all the assumptions) and share it among the pipelines for other possible vaapi elements that request it. 

these bits need to be in place first:

Saddly, the bolts for handling a drm fd context are not placed (only for X11 and Wayland) -- if I recall correctly.

which they currently are not, so while yes this current envvar method is hacky, it's currently the only choice, there are no other options

RushingAlien commented 2 years ago

I understand now, thank you. Nonetheless, I am happy that this works at all right now