-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
Add Enhanced Broadcasting support for Linux #11541
base: master
Are you sure you want to change the base?
Add Enhanced Broadcasting support for Linux #11541
Conversation
UI/system-info-posix.cpp
Outdated
|
||
static bool get_distribution_info(string &distro, string &version) | ||
{ | ||
ifstream file("/etc/os-release"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a Flatpak context, this file should not be relied on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks tytan652. Is there something else within a flatpak that can be relied upon?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The presence of /.flatpak-info
and it's content can be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I'll look into that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added parsing of the /.flatpak-info
in addition to /etc/os-release
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to my comment on Tytan's comment about VAAPI settings migration, these are the only issues I see so far.
UI/system-info-posix.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so for the all of the UI/system-info-posix.cpp
changes, there seems to be a bit of a mix between using raw pointers and references.
static void trim_ws(std::string &s)
static bool get_distribution_info(string &distro, string &version)
static bool get_cpu_freq(uint32_t *cpu_freq)
static bool get_drm_card_info(uint8_t *card_idx, struct drm_card_info *dci)
static void adjust_gpu_model(std::string *model)
bool compare_match_strength(const drm_card_info &a, const drm_card_info &b)
I'm not entirely sure why pointers were used in certain cases here like this versus references. In C this would be understandable but in C++ this just adds unnecessarily unsafe code. Might want to fix these (and any other similar cases in here I haven't spotted) to use references.
If you need the ability to pass nullptr
(which I don't quite see), that would also make sense, but I would probably try to see if that's absolutely necessary, and if so, to check to see if there's a safer way of passing that (e.g. std::optional
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. I've cleaned this up with the latest commits. It's more consistent now and using references instead of pointers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Lain-B Looks like these have been addressed?
UI/system-info-posix.cpp
Outdated
} | ||
} | ||
|
||
bool compare_match_strength(const drm_card_info &a, const drm_card_info &b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless this function is used in a different translation unit, might want to mark it as static.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also recommend checking other newly added non-exported functions elsewhere where this situation might apply, but this is just the one I noticed at first glance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless this function is used in a different translation unit, might want to mark it as static.
Or for better C++-isms, put them into an anonymous (unnamed) namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've put almost all functions in an anonymous namespace and dropped "static" for these. It's cleaner from perspective. Thanks for the suggestion, it makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Lain-B looks like this has been addressed?
69c3d29
to
efd4f5e
Compare
UI/system-info-posix.cpp
Outdated
distro = ""; | ||
version = ""; | ||
|
||
if (std::filesystem::exists(systemd_file)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong priority, Flatpak should be checked first.
Runtime can add an os-release file for compatibility, but has been proven to be an issue (e.g. 6.2 was still showing 5.15 in a lsb-release made for compat) , let's avoid it to happen again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks tytan652. I reversed the parsing order and pushed the update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tytan652 has this been addressed?
efd4f5e
to
dd12c61
Compare
Just wanted to add my feedback for future reviewers: The only thing that was odd was that the Twitch Inspector doesn't show any of the streams when in Bandwidth Testing mode, but it's showing them fine for a Live Broadcast. I don't think that's related to this PR though and more of an Inspector thing. |
Yeah in bandwidth testing mode the data doesn't actually get processed, so it doesn't log codecs etc. |
Add graphics APIs to obtain the GPU driver version and renderer strings, as well as GDDR memory sizes. The GDDR memory sizes include the dmem (dedicated memory on the GPU) and smem (shared CPU memory used by the GPU but resides in the CPU DDR). The version and renderer strings are needed for identification purposes, for example enhanced broadcasting used by Twitch, to associate the GPU used by OBS with the PCIe-based identification values such as device_id and vendor_id.
`os_get_free_size()` was simply returning 0. For Linux, implement the free size calculation based on the `sysinfo()` system call.
`get_rc_mode()` compares the incoming rate control mode string to the .name member of rc_mode_t, and the table entries are all upper-case. This caused a crash when the incoming string is set to "cbr" instead of "CBR". Make the string comparison case insensitive.
VAAPI encoders deviate from other encoders (e.g. AMF, NVENC) with the "profile" setting being an integer instead of a string. With enhanced broadcasting, "profile" is signalled as a string. Convert the string-based profile to the appropriate integer-based profile for VAAPI encoders as a workaround, until VAAPI supports string-based "profile" (if ever).
Enhanced broadcasting requires system information to be gathered on the client and submitted to the GetClientConfiguration request in order to obtain a valid response from the server. This commit adds support for gathering the required information on Linux-based systems.
dd12c61
to
326db9f
Compare
GRAPHICS_IMPORT_OPTIONAL(gpu_get_smem); | ||
GRAPHICS_IMPORT_OPTIONAL(gpu_get_dmem); | ||
GRAPHICS_IMPORT_OPTIONAL(gpu_get_driver_version); | ||
GRAPHICS_IMPORT_OPTIONAL(gpu_get_renderer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer these in the same order they are declared/defined.
uint64_t gs_get_gpu_dmem(void) | ||
{ | ||
return gs_valid("gs_get_gpu_dmem") ? thread_graphics->exports.gpu_get_dmem() : 0; | ||
} | ||
|
||
uint64_t gs_get_gpu_smem(void) | ||
{ | ||
return gs_valid("gs_get_gpu_smem") ? thread_graphics->exports.gpu_get_smem() : 0; | ||
} | ||
|
||
const char *gs_get_driver_version(void) | ||
{ | ||
return gs_valid("gs_get_driver_version") ? thread_graphics->exports.gpu_get_driver_version() : NULL; | ||
} | ||
|
||
const char *gs_get_renderer(void) | ||
{ | ||
return gs_valid("gs_get_renderer") ? thread_graphics->exports.gpu_get_renderer() : NULL; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer these in the same order they are declared/defined in the header.
UI/window-basic-settings.cpp
Outdated
// Enhanced Broadcasting works on Windows and Linux. For other | ||
// OS variants, only enable the GUI controls if developer mode | ||
// was invoked. | ||
#if (!defined(__linux__) && !defined(_WIN32)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will probably conflict with the PR to enable TEB on macOS.
#ifndef _WIN32 | ||
// Enhanced Broadcasting works on Windows and Linux. For other | ||
// OS variants, only enable the GUI controls if developer mode | ||
// was invoked. | ||
#if (!defined(__linux__) && !defined(_WIN32)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will need updated to account for #11440 being merged.
*/ | ||
if (dmem < 0) | ||
dmem = 0; | ||
return (uint64_t)dmem; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer a blank line after an un-bracketed if
, or just enclose the if
in braces.
while (!!rc_mode->name && strcmp(rc_mode->name, name) != 0) | ||
while (!!rc_mode->name && astrcmpi(rc_mode->name, name) != 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the rationale for this change?
/* VAAPI-based encoders unfortunately use an integer for "profile". | ||
* Until a string-based "profile" can be used with VAAPI, find the | ||
* corresponding integer value and update the settings with an | ||
* integer-based "profile". | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines can be wrapped at 120 columns.
* integer-based "profile". | ||
*/ | ||
if (strstr(encoder_type, "vaapi")) { | ||
// Move the "profile" string to "profile_str" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For comments using complete sentences, add final punctuation at the end.
/* Get the amount of dedicated GDDR memory, aka VRAM, in | ||
* units of kilobytes. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines can be wrapped at 120 columns.
dmem = 0; | ||
if (total_mem < 0) | ||
total_mem = 0; | ||
return (uint64_t)total_mem - dmem; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer a blank line after an un-bracketed if
, or enclose all if
s in braces.
Description
TEB (Twitch Enhanced Broadcasting) requires the client to gather information about the host, such as which GPU(s) are available, memory sizes, OS version, etc..., and send that information to a server which then responds with a configuration set for the client to use with multitrack encoding. TEB originally supported Windows, and this PR adds support for Linux-based operating systems.
TEB on Linux supports NVIDIA and AMD GPUs, and Intel GPUs as of 2024.12.17. Intel GPUs with Linux seem to work at least with a flatpak build. For NVIDIA GPUs, NVENC is used and the configurations from the server are currently identical between Windows and Linux. For AMD GPUs, AMF is used on Windows and VAAPI is used on Linux; AMF on Linux is not currently supported for TEB. AMF on Linux might be supported in the future.
Motivation and Context
From the client encoding perspective, Enhanced Broadcasting was originally envisioned to support Windows, Linux, and MacOS. This PR addresses the market need to expand support for Linux-based users.
How Has This Been Tested?
The code has been tested in the TEB beta program and also by the primary developer (@lexano-ivs) on a host setup specifically to test TEB on Linux. This host includes:
The code was tested against multiple configurations, including single & dual dGPU configurations, swapping the primary/secondary GPU between NVIDIA and AMD, and across the 3 Linux operating systems. DEB-based builds, local builds, and flatpak builds were also tested.
Refer to TEB Installation Instructions for additional context.
Types of changes
Checklist: