Merge branch 'obsproject:master' into master

This commit is contained in:
4aiman 2025-05-27 12:54:30 +03:00 • committed by GitHub
commit 19de6712e8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 258 additions and 154 deletions

View file

@ -68,7 +68,7 @@ jobs:
submodules: recursive submodules: recursive
token: ${{ secrets.CROWDIN_SYNC_GITHUB_PAT }} token: ${{ secrets.CROWDIN_SYNC_GITHUB_PAT }}
fetch-depth: 0 fetch-depth: 0
- uses: obsproject/obs-crowdin-sync/download@84628cad04d2423e02443c64965cb834b4c5a245 - uses: obsproject/obs-crowdin-sync/download@6066f54d3615e39a228b6ccd1a9884953ba3ab05
steam-upload: steam-upload:
name: Upload Steam Builds 🚂 name: Upload Steam Builds 🚂

View file

@ -154,7 +154,7 @@ jobs:
- name: Upload US English Language Files 🇺🇸 - name: Upload US English Language Files 🇺🇸
if: steps.checks.outcome == 'success' && fromJSON(steps.checks.outputs.hasChangedFiles) if: steps.checks.outcome == 'success' && fromJSON(steps.checks.outputs.hasChangedFiles)
uses: obsproject/obs-crowdin-sync/upload@84628cad04d2423e02443c64965cb834b4c5a245 uses: obsproject/obs-crowdin-sync/upload@6066f54d3615e39a228b6ccd1a9884953ba3ab05
env: env:
CROWDIN_PAT: ${{ secrets.CROWDIN_SYNC_CROWDIN_PAT }} CROWDIN_PAT: ${{ secrets.CROWDIN_SYNC_CROWDIN_PAT }}
GITHUB_EVENT_BEFORE: ${{ steps.nightly-checks.outputs.lastNightly }} GITHUB_EVENT_BEFORE: ${{ steps.nightly-checks.outputs.lastNightly }}

View file

@ -134,7 +134,7 @@
"GPU_PRIORITY_VAL": {"type": "STRING", "value": "$penv{GPU_PRIORITY_VAL}"}, "GPU_PRIORITY_VAL": {"type": "STRING", "value": "$penv{GPU_PRIORITY_VAL}"},
"VIRTUALCAM_GUID": {"type": "STRING", "value": "A3FCE0F5-3493-419F-958A-ABA1250EC20B"}, "VIRTUALCAM_GUID": {"type": "STRING", "value": "A3FCE0F5-3493-419F-958A-ABA1250EC20B"},
"ENABLE_AJA": false, "ENABLE_AJA": false,
"ENABLE_BROWSER": false, "ENABLE_BROWSER": true,
"ENABLE_SCRIPTING": false, "ENABLE_SCRIPTING": false,
"ENABLE_VST": false "ENABLE_VST": false
} }

View file

@ -58,7 +58,7 @@ Coding Guidelines
- Comments and names of variables/functions/etc. must be in English - Comments and names of variables/functions/etc. must be in English
- Formatting scripts (mac0S/Linux only) are available `here <./build-aux>`__ - Formatting scripts (macOS/Linux only) are available `here <./build-aux>`__
Commit Guidelines Commit Guidelines
----------------- -----------------

View file

@ -11,8 +11,8 @@
{ {
"type": "git", "type": "git",
"url": "https://github.com/FFmpeg/nv-codec-headers.git", "url": "https://github.com/FFmpeg/nv-codec-headers.git",
"tag": "n13.0.19.0", "tag": "n12.2.72.0",
"commit": "e844e5b26f46bb77479f063029595293aa8f812d" "commit": "c69278340ab1d5559c7d7bf0edf615dc33ddbba7"
} }
] ]
} }

View file

@ -25,8 +25,8 @@
{ {
"type": "git", "type": "git",
"url": "https://github.com/FFmpeg/FFmpeg.git", "url": "https://github.com/FFmpeg/FFmpeg.git",
"tag": "n7.1", "tag": "n7.1.1",
"commit": "b08d7969c550a804a59511c7b83f2dd8cc0499b8", "commit": "db69d06eeeab4f46da15030a80d539efb4503ca8",
"disable-shallow-clone": true "disable-shallow-clone": true
}, },
{ {

View file

@ -1,28 +1,28 @@
{ {
"dependencies": { "dependencies": {
"prebuilt": { "prebuilt": {
"version": "2025-03-06", "version": "2025-05-23",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download", "baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-Built obs-deps", "label": "Pre-Built obs-deps",
"hashes": { "hashes": {
"macos-universal": "e32bd7dbfef37931147781d8d657a4328bdcf1148008980539c07d4a18b54965", "macos-universal": "7b1448581b92c6f8d4e2f9b1b10eb318ebfc4df7255638e05bacb49b620e190d",
"windows-x64": "22d9f923eb6d2cbdde1ff64efb9638a88629ba23a4b70ed7a52e98a81b740275", "windows-x64": "88dc7bab50542b4b58194cdd5d7e6f4b73cde7c0d1ee7a040a6d9c9df05187b1",
"windows-x86": "deb4c08514be0b1b1e155305ddd9cb936d906b389b3a54b3a9e748ea842904af", "windows-x86": "f6d01c7c31f14cb245803963a2f9af42b01b63f9baadf6259e56843d94eae8c4",
"windows-arm64": "80e6776c7501a1b06d804ad80e55718fe24e1aa3eae736cbb8955b884ecd5c8a" "windows-arm64": "43520957736d332b0a545c320db7087762e394ef78243d72769fb59794e00913"
} }
}, },
"qt6": { "qt6": {
"version": "2025-03-06", "version": "2025-05-23",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download", "baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-Built Qt6", "label": "Pre-Built Qt6",
"hashes": { "hashes": {
"macos-universal": "51bb5e2e546443ae442f74870a2c0973f1c07d2b5628cd1d530d53ff3f668f04", "macos-universal": "d4945fe719d31d353dc76298f58823d7891126e33af5029f763427ea9f80bfaa",
"windows-x64": "84f83f1c3656b53a7c4ba8f8248818ba8684786e3e47123b679406e42d8b6a54", "windows-x64": "bd80383dc799c0bba2f7fae793613b3fbd2cc3a3712b3d3b63b490721d187d9e",
"windows-arm64": "f03bd8f9df6f6d668e1f3a0bbf8c35a5f80ca27c28a5bfe4549ff230791ecb1b" "windows-arm64": "35a06786c460031571134f0e2ba288a9dce4ddf044686f6af48fae52728d1796"
}, },
"debugSymbols": { "debugSymbols": {
"windows-x64": "32afba76af47f6fb2d8aa1b90b981b56cc2f2b9a5552934ad5446ddc20dec2a9", "windows-x64": "9c9a15c5dbe59eb6a1c31c06b7208f3c4403671fbdfaef341cac3beb7af24ea1",
"windows-arm64": "36bfa31109da5273e93e68faa62b0cf4a89092147c5203f1a17d2ec7d1c814b4" "windows-arm64": "a6229cc9e5e08a22921b1fa8fb10fc6e36e88f692fa2e6921c1b61b7a3161c81"
} }
}, },
"cef": { "cef": {
@ -34,7 +34,8 @@
"macos-arm64": "1bb59dbb759150e170796f641a4a84c59c0dea4ffef89477e9d811520af5d15a", "macos-arm64": "1bb59dbb759150e170796f641a4a84c59c0dea4ffef89477e9d811520af5d15a",
"ubuntu-x86_64": "cb7225c7a937ac4cdc9c41700061f45cccc640d696902357782e57f8250bf43a", "ubuntu-x86_64": "cb7225c7a937ac4cdc9c41700061f45cccc640d696902357782e57f8250bf43a",
"ubuntu-aarch64": "f92df7f076bdc8cac2e3c77e27be418008b7168723201cb73fdbc2f6d91bc778", "ubuntu-aarch64": "f92df7f076bdc8cac2e3c77e27be418008b7168723201cb73fdbc2f6d91bc778",
"windows-x64": "922efbda1f2f8be9e5b2754d878a14d90afc81f04e94fc9101a7513e2b5cecc1" "windows-x64": "922efbda1f2f8be9e5b2754d878a14d90afc81f04e94fc9101a7513e2b5cecc1",
"windows-arm64": "df9df4bd85826b4c071c6db404fd59cf93efd9c58ec3ab64e204466ae19bb02a"
}, },
"revision": { "revision": {
"macos-x86_64": 3, "macos-x86_64": 3,

View file

@ -198,7 +198,7 @@ Initialization, Shutdown, and Information
--------------------- ---------------------
.. function:: void obs_set_video_sdr_white_level(float sdr_white_level, float hdr_nominal_peak_level) .. function:: void obs_set_video_levels(float sdr_white_level, float hdr_nominal_peak_level)
Sets the current video levels. Sets the current video levels.

View file

@ -26,6 +26,9 @@
#if !defined(_WIN32) && !defined(__APPLE__) #if !defined(_WIN32) && !defined(__APPLE__)
#include <obs-nix-platform.h> #include <obs-nix-platform.h>
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
#include <qpa/qplatformnativeinterface.h>
#endif
#endif #endif
#include <qt-wrappers.hpp> #include <qt-wrappers.hpp>
@ -38,9 +41,6 @@
#else #else
#include <QSocketNotifier> #include <QSocketNotifier>
#endif #endif
#if !defined(_WIN32) && !defined(__APPLE__)
#include <qpa/qplatformnativeinterface.h>
#endif
#ifdef _WIN32 #ifdef _WIN32
#include <sstream> #include <sstream>
@ -230,11 +230,13 @@ bool OBSApp::InitGlobalConfigDefaults()
#ifdef _WIN32 #ifdef _WIN32
config_set_default_bool(appConfig, "Audio", "DisableAudioDucking", true); config_set_default_bool(appConfig, "Audio", "DisableAudioDucking", true);
#endif
#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__)
config_set_default_bool(appConfig, "General", "BrowserHWAccel", true); config_set_default_bool(appConfig, "General", "BrowserHWAccel", true);
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
config_set_default_bool(appConfig, "General", "BrowserHWAccel", true);
config_set_default_bool(appConfig, "Video", "DisableOSXVSync", true); config_set_default_bool(appConfig, "Video", "DisableOSXVSync", true);
config_set_default_bool(appConfig, "Video", "ResetOSXVSyncOnExit", true); config_set_default_bool(appConfig, "Video", "ResetOSXVSyncOnExit", true);
#endif #endif
@ -1048,21 +1050,37 @@ bool OBSApp::OBSInit()
#if !defined(_WIN32) && !defined(__APPLE__) #if !defined(_WIN32) && !defined(__APPLE__)
if (QApplication::platformName() == "xcb") { if (QApplication::platformName() == "xcb") {
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
auto native = qGuiApp->nativeInterface<QNativeInterface::QX11Application>();
obs_set_nix_platform_display(native->display());
#endif
obs_set_nix_platform(OBS_NIX_PLATFORM_X11_EGL); obs_set_nix_platform(OBS_NIX_PLATFORM_X11_EGL);
blog(LOG_INFO, "Using EGL/X11"); blog(LOG_INFO, "Using EGL/X11");
} }
#ifdef ENABLE_WAYLAND #ifdef ENABLE_WAYLAND
if (QApplication::platformName().contains("wayland")) { if (QApplication::platformName().contains("wayland")) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
auto native = qGuiApp->nativeInterface<QNativeInterface::QWaylandApplication>();
obs_set_nix_platform_display(native->display());
#endif
obs_set_nix_platform(OBS_NIX_PLATFORM_WAYLAND); obs_set_nix_platform(OBS_NIX_PLATFORM_WAYLAND);
setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
blog(LOG_INFO, "Platform: Wayland"); blog(LOG_INFO, "Platform: Wayland");
} }
#endif #endif
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface(); QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface();
obs_set_nix_platform_display(native->nativeResourceForIntegration("display")); obs_set_nix_platform_display(native->nativeResourceForIntegration("display"));
#endif #endif
#endif
#ifdef __APPLE__ #ifdef __APPLE__
setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
@ -1075,7 +1093,7 @@ bool OBSApp::OBSInit()
obs_set_ui_task_handler(ui_task_handler); obs_set_ui_task_handler(ui_task_handler);
#if defined(_WIN32) || defined(__APPLE__) #if defined(_WIN32) || defined(__APPLE__) || defined(__linux__)
bool browserHWAccel = config_get_bool(appConfig, "General", "BrowserHWAccel"); bool browserHWAccel = config_get_bool(appConfig, "General", "BrowserHWAccel");
OBSDataAutoRelease settings = obs_data_create(); OBSDataAutoRelease settings = obs_data_create();

View file

@ -2,6 +2,9 @@ target_sources(obs-studio PRIVATE utility/platform-x11.cpp utility/system-info-p
target_compile_definitions(obs-studio PRIVATE OBS_INSTALL_PREFIX="${OBS_INSTALL_PREFIX}") target_compile_definitions(obs-studio PRIVATE OBS_INSTALL_PREFIX="${OBS_INSTALL_PREFIX}")
target_link_libraries(obs-studio PRIVATE Qt::GuiPrivate Qt::DBus procstat) target_link_libraries(obs-studio PRIVATE Qt::GuiPrivate Qt::DBus procstat)
find_package(Libpci REQUIRED)
target_link_libraries(obs-studio PRIVATE Libpci::pci)
if(TARGET OBS::python) if(TARGET OBS::python)
find_package(Python REQUIRED COMPONENTS Interpreter Development) find_package(Python REQUIRED COMPONENTS Interpreter Development)
target_link_libraries(obs-studio PRIVATE Python::Python) target_link_libraries(obs-studio PRIVATE Python::Python)

View file

@ -70,12 +70,14 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_) : tre
vis->setChecked(sourceVisible); vis->setChecked(sourceVisible);
vis->setAccessibleName(QTStr("Basic.Main.Sources.Visibility")); vis->setAccessibleName(QTStr("Basic.Main.Sources.Visibility"));
vis->setAccessibleDescription(QTStr("Basic.Main.Sources.VisibilityDescription").arg(name)); vis->setAccessibleDescription(QTStr("Basic.Main.Sources.VisibilityDescription").arg(name));
vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
lock = new QCheckBox(); lock = new QCheckBox();
lock->setProperty("class", "checkbox-icon indicator-lock"); lock->setProperty("class", "checkbox-icon indicator-lock");
lock->setChecked(obs_sceneitem_locked(sceneitem)); lock->setChecked(obs_sceneitem_locked(sceneitem));
lock->setAccessibleName(QTStr("Basic.Main.Sources.Lock")); lock->setAccessibleName(QTStr("Basic.Main.Sources.Lock"));
lock->setAccessibleDescription(QTStr("Basic.Main.Sources.LockDescription").arg(name)); lock->setAccessibleDescription(QTStr("Basic.Main.Sources.LockDescription").arg(name));
lock->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
label = new OBSSourceLabel(source); label = new OBSSourceLabel(source);
label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);

View file

@ -42,6 +42,7 @@ Projector.Window="New window"
Projector.Title="Projector" Projector.Title="Projector"
Projector.Title.Scene="Scene: %1" Projector.Title.Scene="Scene: %1"
Projector.Title.Source="Source: %1" Projector.Title.Source="Source: %1"
Projector.Title.Multiview="Multiview"
Projector.ResizeWindowToContent="Fit window to content" Projector.ResizeWindowToContent="Fit window to content"
Clear="Clear" Clear="Clear"
Revert="Revert" Revert="Revert"
@ -956,6 +957,13 @@ Basic.Settings.Appearance.General="General"
Basic.Settings.Appearance.General.Theme="Theme" Basic.Settings.Appearance.General.Theme="Theme"
Basic.Settings.Appearance.General.Variant="Style" Basic.Settings.Appearance.General.Variant="Style"
Basic.Settings.Appearance.General.NoVariant="No Styles Available" Basic.Settings.Appearance.General.NoVariant="No Styles Available"
Basic.Settings.Appearance.FontScale="Font Size"
Basic.Settings.Appearance.Density="Density"
Basic.Settings.Appearance.Classic="Classic"
Basic.Settings.Appearance.Compact="Compact"
Basic.Settings.Appearance.Normal="Normal"
Basic.Settings.Appearance.Comfortable="Comfortable"
Basic.Settings.Appearance.OptionsWarning="Some appearance options are not available for this style."
# basic mode 'stream' settings # basic mode 'stream' settings
Basic.Settings.Stream="Stream" Basic.Settings.Stream="Stream"

View file

@ -1,4 +1 @@
<?xml version="1.0" encoding="UTF-8"?> <svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><style>.a{fill:#fefefe}</style><path class="a" d="m1 1h1.8c0.5 0 0.9 0.2 1.3 0.6l4 4.1 4.1-4.1c0.5-0.5 0.8-0.6 1.2-0.6h1.8v1.8c0 0.5 0 1-0.4 1.4l-4.1 4.2 4 4.1c0.4 0.3 0.5 0.8 0.5 1.3v1.8h-1.8c-0.4 0-0.9-0.1-1.2-0.5l-4.1-4.2-4 4.2c-0.4 0.4-0.8 0.5-1.3 0.5h-1.8v-1.8c0-0.5 0.2-1 0.5-1.3l4.1-4.1-4.1-4.2c-0.4-0.4-0.5-0.9-0.5-1.4z"/></svg>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 4 4 h 1 h 0.03125 c 0.253906 0.011719 0.511719 0.128906 0.6875 0.3125 l 2.28125 2.28125 l 2.3125 -2.28125 c 0.265625 -0.230469 0.445312 -0.304688 0.6875 -0.3125 h 1 v 1 c 0 0.285156 -0.035156 0.550781 -0.25 0.75 l -2.28125 2.28125 l 2.25 2.25 c 0.1875 0.1875 0.28125 0.453125 0.28125 0.71875 v 1 h -1 c -0.265625 0 -0.53125 -0.09375 -0.71875 -0.28125 l -2.28125 -2.28125 l -2.28125 2.28125 c -0.1875 0.1875 -0.453125 0.28125 -0.71875 0.28125 h -1 v -1 c 0 -0.265625 0.09375 -0.53125 0.28125 -0.71875 l 2.28125 -2.25 l -2.28125 -2.28125 c -0.210938 -0.195312 -0.304688 -0.46875 -0.28125 -0.75 z m 0 0" fill="#fefefe"/>
</svg>

Before

Width:  |  Height:  |  Size: 767 B

After

Width:  |  Height:  |  Size: 434 B

Before After
Before After

View file

@ -1,4 +1 @@
<?xml version="1.0" encoding="UTF-8"?> <svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><style>.a{fill:#202020}</style><path class="a" d="m1 1h1.8c0.5 0 0.9 0.2 1.3 0.6l4 4.1 4.1-4.1c0.5-0.5 0.8-0.6 1.2-0.6h1.8v1.8c0 0.5 0 1-0.4 1.4l-4.1 4.2 4 4.1c0.4 0.3 0.5 0.8 0.5 1.3v1.8h-1.8c-0.4 0-0.9-0.1-1.2-0.5l-4.1-4.2-4 4.2c-0.4 0.4-0.8 0.5-1.3 0.5h-1.8v-1.8c0-0.5 0.2-1 0.5-1.3l4.1-4.1-4.1-4.2c-0.4-0.4-0.5-0.9-0.5-1.4z"/></svg>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 4 4 h 1 h 0.03125 c 0.253906 0.011719 0.511719 0.128906 0.6875 0.3125 l 2.28125 2.28125 l 2.3125 -2.28125 c 0.265625 -0.230469 0.445312 -0.304688 0.6875 -0.3125 h 1 v 1 c 0 0.285156 -0.035156 0.550781 -0.25 0.75 l -2.28125 2.28125 l 2.25 2.25 c 0.1875 0.1875 0.28125 0.453125 0.28125 0.71875 v 1 h -1 c -0.265625 0 -0.53125 -0.09375 -0.71875 -0.28125 l -2.28125 -2.28125 l -2.28125 2.28125 c -0.1875 0.1875 -0.453125 0.28125 -0.71875 0.28125 h -1 v -1 c 0 -0.265625 0.09375 -0.53125 0.28125 -0.71875 l 2.28125 -2.25 l -2.28125 -2.28125 c -0.210938 -0.195312 -0.304688 -0.46875 -0.28125 -0.75 z m 0 0" fill="#202020"/>
</svg>

Before

Width:  |  Height:  |  Size: 767 B

After

Width:  |  Height:  |  Size: 434 B

Before After
Before After

View file

@ -495,6 +495,7 @@ QMenu::right-arrow {
/* Top Menu Bar Items */ /* Top Menu Bar Items */
QMenuBar::item { QMenuBar::item {
background-color: transparent; background-color: transparent;
padding: var(--padding_large) var(--padding_xlarge);
} }
QMenuBar::item:selected { QMenuBar::item:selected {
@ -548,6 +549,11 @@ SourceTreeItem .checkbox-icon {
margin-left: var(--spacing_large); margin-left: var(--spacing_large);
} }
SourceTree .indicator-expand {
margin-right: var(--spacing_large);
margin-left: 0;
}
QMenu::item:selected, QMenu::item:selected,
QListView::item:selected, QListView::item:selected,
QListWidget::item:selected { QListWidget::item:selected {
@ -651,6 +657,10 @@ QDockWidget::float-button {
border-radius: var(--border_radius); border-radius: var(--border_radius);
background: transparent; background: transparent;
margin-right: 1px; margin-right: 1px;
min-width: var(--icon_base);
min-height: var(--icon_base);
icon-size: var(--icon_base);
padding: var(--padding_base);
} }
QDockWidget::close-button:hover, QDockWidget::close-button:hover,
@ -660,6 +670,7 @@ QDockWidget::float-button:hover {
QDockWidget::close-button:pressed, QDockWidget::close-button:pressed,
QDockWidget::float-button:pressed { QDockWidget::float-button:pressed {
background: var(--button_bg_down);
padding: 1px -1px -1px 1px; padding: 1px -1px -1px 1px;
} }

View file

@ -16,8 +16,8 @@
--grey7: rgb(25,27,38); --grey7: rgb(25,27,38);
--grey8: rgb(21,22,23); --grey8: rgb(21,22,23);
--primary: rgb(0,188,212); --primary: rgb(145,76,103);
--primary_light: rgb(145,76,103); --primary_light: rgb(0,188,212);
--primary_lighter: rgb(240,96,146); --primary_lighter: rgb(240,96,146);
--primary_dark: rgb(89,66,79); --primary_dark: rgb(89,66,79);
--primary_darker: rgb(25,27,38); --primary_darker: rgb(25,27,38);
@ -32,17 +32,17 @@
--input_bg_hover: var(--grey7); --input_bg_hover: var(--grey7);
--input_bg_focus: var(--grey7); --input_bg_focus: var(--grey7);
--list_item_bg_selected: var(--primary); --list_item_bg_selected: var(--primary_light);
--list_item_bg_hover: var(--primary_light); --list_item_bg_hover: var(--primary);
--input_border: var(--grey1); --input_border: var(--grey1);
--input_border_hover: var(--primary); --input_border_hover: var(--primary_light);
--input_border_focus: var(--primary); --input_border_focus: var(--primary_light);
--spacing_input: var(--spacing_base); --spacing_input: var(--spacing_base);
--button_bg: var(--primary); --button_bg: var(--primary_light);
--button_bg_hover: var(--primary_light); --button_bg_hover: var(--primary);
--button_bg_down: var(--primary_dark); --button_bg_down: var(--primary_dark);
--button_bg_disabled: var(--grey6); --button_bg_disabled: var(--grey6);
@ -50,7 +50,7 @@
--button_bg_red_hover: rgb(116,32,49); --button_bg_red_hover: rgb(116,32,49);
--button_bg_red_down: rgb(63,21,30); --button_bg_red_down: rgb(63,21,30);
--button_border: var(--primary); --button_border: var(--primary_light);
--button_border_hover: var(--button_bg_hover); --button_border_hover: var(--button_bg_hover);
--button_border_focus: var(--button_bg_hover); --button_border_focus: var(--button_bg_hover);
@ -62,15 +62,15 @@
--tab_border: var(--grey3); --tab_border: var(--grey3);
--tab_border_hover: var(--grey1); --tab_border_hover: var(--grey1);
--tab_border_focus: var(--grey1); --tab_border_focus: var(--grey1);
--tab_border_selected: var(--primary_light); --tab_border_selected: var(--primary);
--scrollbar: var(--grey2); --scrollbar: var(--grey2);
--scrollbar_hover: var(--primary_light); --scrollbar_hover: var(--primary);
--scrollbar_down: var(--grey3); --scrollbar_down: var(--grey3);
--scrollbar_border: var(--primary_light); --scrollbar_border: var(--primary);
--toolbutton_bg: var(--grey3); --toolbutton_bg: var(--grey3);
--toolbutton_bg_hover: var(--primary_light); --toolbutton_bg_hover: var(--primary);
--toolbutton_bg_down: var(--primary_dark); --toolbutton_bg_down: var(--primary_dark);
--toolbutton_bg_disabled: var(--grey4); --toolbutton_bg_disabled: var(--grey4);
} }
@ -95,6 +95,10 @@ QDoubleSpinBox {
border-color: var(--input_border); border-color: var(--input_border);
} }
QPushButton {
border-width: 2px;
}
QMenu::item:selected, QMenu::item:selected,
QListWidget::item:selected, QListWidget::item:selected,
SceneTree::item:selected, SceneTree::item:selected,
@ -110,7 +114,7 @@ QMenu::item:selected:hover,
QListWidget::item:selected:hover, QListWidget::item:selected:hover,
SceneTree::item:selected:hover, SceneTree::item:selected:hover,
SourceTree::item:selected:hover { SourceTree::item:selected:hover {
background-color: var(--primary); background-color: var(--primary_light);
} }
QToolBar { QToolBar {
@ -123,6 +127,16 @@ QPushButton:disabled {
border-color: var(--grey3); border-color: var(--grey3);
} }
QPushButton:checked,
QPushButton.state-active {
border-color: var(--primary_lighter);
}
QPushButton:checked:hover,
QPushButton:checked:focus {
border-color: var(--primary_light);
}
QToolButton, QToolButton,
QPushButton[toolButton="true"] { QPushButton[toolButton="true"] {
background-color: var(--toolbutton_bg); background-color: var(--toolbutton_bg);
@ -131,8 +145,8 @@ QPushButton[toolButton="true"] {
QToolButton:hover, QToolButton:hover,
QToolButton:focus { QToolButton:focus {
border-color: var(--primary_light); border-color: var(--primary);
background-color: var(--primary_light); background-color: var(--primary);
} }
QToolButton:pressed, QToolButton:pressed,
@ -185,7 +199,7 @@ QTabBar::tab {
} }
QTabBar::tab:top:selected { QTabBar::tab:top:selected {
border-bottom: 2px solid var(--primary_light); border-bottom: 2px solid var(--primary);
} }
QTabBar QToolButton { QTabBar QToolButton {
@ -219,14 +233,3 @@ VolumeMeter {
qproperty-majorTickColor: palette(window-text); qproperty-majorTickColor: palette(window-text);
qproperty-minorTickColor: palette(mid); qproperty-minorTickColor: palette(mid);
} }
/* Primary Control Button Checked Coloring */
#streamButton:!hover:!pressed.state-active,
#recordButton:!hover:!pressed.state-active,
#pauseRecordButton:!hover:!pressed.state-active,
#replayBufferButton:!hover:!pressed.state-active,
#virtualCamButton:!hover:!pressed.state-active,
#modeSwitch:!hover:!pressed.state-active,
#broadcastButton:!hover:!pressed.state-active {
background: var(--primary_light);
}

View file

@ -249,63 +249,6 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<widget class="QPushButton" name="previewZoomInButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>Basic.MainMenu.Edit.Scale.ZoomIn</string>
</property>
<property name="accessibleName">
<string>Basic.MainMenu.Edit.Scale.ZoomIn</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="obs.qrc">
<normaloff>:/res/images/plus.svg</normaloff>:/res/images/plus.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
<property name="toolButton" stdset="0">
<bool>true</bool>
</property>
<property name="class" stdset="0">
<string>icon-plus</string>
</property>
</widget>
</item>
<item>
<widget class="OBSPreviewScalingLabel" name="previewScalePercent">
<property name="text">
<string>100%</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="previewZoomOutButton"> <widget class="QPushButton" name="previewZoomOutButton">
<property name="sizePolicy"> <property name="sizePolicy">
@ -327,10 +270,10 @@
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Basic.MainMenu.Edit.Scale.ZoomOut</string> <string>Basic.MainMenu.Edit.Scale.ZoomIn</string>
</property> </property>
<property name="accessibleName"> <property name="accessibleName">
<string>Basic.MainMenu.Edit.Scale.ZoomOut</string> <string>Basic.MainMenu.Edit.Scale.ZoomIn</string>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
@ -353,6 +296,63 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="OBSPreviewScalingLabel" name="previewScalePercent">
<property name="text">
<string>100%</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="previewZoomInButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>Basic.MainMenu.Edit.Scale.ZoomOut</string>
</property>
<property name="accessibleName">
<string>Basic.MainMenu.Edit.Scale.ZoomOut</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="obs.qrc">
<normaloff>:/res/images/plus.svg</normaloff>:/res/images/plus.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
<property name="toolButton" stdset="0">
<bool>true</bool>
</property>
<property name="class" stdset="0">
<string>icon-plus</string>
</property>
</widget>
</item>
<item> <item>
<widget class="OBSPreviewScalingComboBox" name="previewScalingMode"> <widget class="OBSPreviewScalingComboBox" name="previewScalingMode">
<item> <item>
@ -2027,7 +2027,7 @@
</action> </action>
<action name="actionExportSceneCollection"> <action name="actionExportSceneCollection">
<property name="text"> <property name="text">
<string>Export</string> <string>Basic.MainMenu.Export</string>
</property> </property>
</action> </action>
<action name="actionShowMissingFiles"> <action name="actionShowMissingFiles">
@ -2067,7 +2067,7 @@
</action> </action>
<action name="actionExportProfile"> <action name="actionExportProfile">
<property name="text"> <property name="text">
<string>Export</string> <string>Basic.MainMenu.Export</string>
</property> </property>
</action> </action>
<action name="actionShowSettingsFolder"> <action name="actionShowSettingsFolder">

View file

@ -1023,7 +1023,7 @@
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="appearanceSettingLabelFontScale"> <widget class="QLabel" name="appearanceSettingLabelFontScale">
<property name="text"> <property name="text">
<string>Font Size</string> <string>Basic.Settings.Appearance.FontScale</string>
</property> </property>
<property name="buddy"> <property name="buddy">
<cstring>appearanceFontScale</cstring> <cstring>appearanceFontScale</cstring>
@ -1116,7 +1116,7 @@
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_20"> <widget class="QLabel" name="label_20">
<property name="text"> <property name="text">
<string>Density</string> <string>Basic.Settings.Appearance.Density</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -1147,7 +1147,7 @@
<item> <item>
<widget class="QPushButton" name="appearanceDensity1"> <widget class="QPushButton" name="appearanceDensity1">
<property name="text"> <property name="text">
<string>Classic</string> <string>Basic.Settings.Appearance.Classic</string>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
@ -1163,7 +1163,7 @@
<item> <item>
<widget class="QPushButton" name="appearanceDensity2"> <widget class="QPushButton" name="appearanceDensity2">
<property name="text"> <property name="text">
<string>Compact</string> <string>Basic.Settings.Appearance.Compact</string>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
@ -1179,7 +1179,7 @@
<item> <item>
<widget class="QPushButton" name="appearanceDensity3"> <widget class="QPushButton" name="appearanceDensity3">
<property name="text"> <property name="text">
<string>Normal</string> <string>Basic.Settings.Appearance.Normal</string>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
@ -1198,7 +1198,7 @@
<item> <item>
<widget class="QPushButton" name="appearanceDensity4"> <widget class="QPushButton" name="appearanceDensity4">
<property name="text"> <property name="text">
<string>Comfortable</string> <string>Basic.Settings.Appearance.Comfortable</string>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
@ -1258,7 +1258,7 @@
<item> <item>
<widget class="QLabel" name="appearanceOptionsWarningLabel"> <widget class="QLabel" name="appearanceOptionsWarningLabel">
<property name="text"> <property name="text">
<string>Some appearance options are not available for this style.</string> <string>Basic.Settings.Appearance.OptionsWarning</string>
</property> </property>
<property name="class" stdset="0"> <property name="class" stdset="0">
<string>text-warning</string> <string>text-warning</string>

View file

@ -0,0 +1 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><style>.a{fill:#202020}</style><path class="a" d="m1 1h1.8c0.5 0 0.9 0.2 1.3 0.6l4 4.1 4.1-4.1c0.5-0.5 0.8-0.6 1.2-0.6h1.8v1.8c0 0.5 0 1-0.4 1.4l-4.1 4.2 4 4.1c0.4 0.3 0.5 0.8 0.5 1.3v1.8h-1.8c-0.4 0-0.9-0.1-1.2-0.5l-4.1-4.2-4 4.2c-0.4 0.4-0.8 0.5-1.3 0.5h-1.8v-1.8c0-0.5 0.2-1 0.5-1.3l4.1-4.1-4.1-4.2c-0.4-0.4-0.5-0.9-0.5-1.4z"/></svg>

After

Width:  |  Height:  |  Size: 434 B

View file

@ -1,5 +1,6 @@
<RCC> <RCC>
<qresource prefix="/res"> <qresource prefix="/res">
<file>images/close.svg</file>
<file>images/save.svg</file> <file>images/save.svg</file>
<file>images/media-pause.svg</file> <file>images/media-pause.svg</file>
<file>images/trash.svg</file> <file>images/trash.svg</file>

View file

@ -530,7 +530,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
#ifdef _WIN32 #ifdef _WIN32
HookWidget(ui->disableAudioDucking, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->disableAudioDucking, CHECK_CHANGED, ADV_CHANGED);
#endif #endif
#if defined(_WIN32) || defined(__APPLE__) #if defined(_WIN32) || defined(__APPLE__) || defined(__linux__)
HookWidget(ui->browserHWAccel, CHECK_CHANGED, ADV_RESTART); HookWidget(ui->browserHWAccel, CHECK_CHANGED, ADV_RESTART);
#endif #endif
HookWidget(ui->filenameFormatting, EDIT_CHANGED, ADV_CHANGED); HookWidget(ui->filenameFormatting, EDIT_CHANGED, ADV_CHANGED);
@ -618,7 +618,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
delete ui->enableNewSocketLoop; delete ui->enableNewSocketLoop;
delete ui->enableLowLatencyMode; delete ui->enableLowLatencyMode;
delete ui->hideOBSFromCapture; delete ui->hideOBSFromCapture;
#ifdef __linux__ #if !defined(__APPLE__) && !defined(__linux__)
delete ui->browserHWAccel; delete ui->browserHWAccel;
delete ui->sourcesGroup; delete ui->sourcesGroup;
#endif #endif
@ -633,7 +633,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
ui->enableNewSocketLoop = nullptr; ui->enableNewSocketLoop = nullptr;
ui->enableLowLatencyMode = nullptr; ui->enableLowLatencyMode = nullptr;
ui->hideOBSFromCapture = nullptr; ui->hideOBSFromCapture = nullptr;
#ifdef __linux__ #if !defined(__APPLE__) && !defined(__linux__)
ui->browserHWAccel = nullptr; ui->browserHWAccel = nullptr;
ui->sourcesGroup = nullptr; ui->sourcesGroup = nullptr;
#endif #endif
@ -2593,7 +2593,7 @@ void OBSBasicSettings::LoadAdvancedSettings()
ui->enableLowLatencyMode->setChecked(enableLowLatencyMode); ui->enableLowLatencyMode->setChecked(enableLowLatencyMode);
ui->enableLowLatencyMode->setToolTip(QTStr("Basic.Settings.Advanced.Network.TCPPacing.Tooltip")); ui->enableLowLatencyMode->setToolTip(QTStr("Basic.Settings.Advanced.Network.TCPPacing.Tooltip"));
#endif #endif
#if defined(_WIN32) || defined(__APPLE__) #if defined(_WIN32) || defined(__APPLE__) || defined(__linux__)
bool browserHWAccel = config_get_bool(App()->GetAppConfig(), "General", "BrowserHWAccel"); bool browserHWAccel = config_get_bool(App()->GetAppConfig(), "General", "BrowserHWAccel");
ui->browserHWAccel->setChecked(browserHWAccel); ui->browserHWAccel->setChecked(browserHWAccel);
prevBrowserAccel = ui->browserHWAccel->isChecked(); prevBrowserAccel = ui->browserHWAccel->isChecked();
@ -3140,7 +3140,7 @@ void OBSBasicSettings::SaveAdvancedSettings()
SaveCheckBox(ui->enableNewSocketLoop, "Output", "NewSocketLoopEnable"); SaveCheckBox(ui->enableNewSocketLoop, "Output", "NewSocketLoopEnable");
SaveCheckBox(ui->enableLowLatencyMode, "Output", "LowLatencyEnable"); SaveCheckBox(ui->enableLowLatencyMode, "Output", "LowLatencyEnable");
#endif #endif
#if defined(_WIN32) || defined(__APPLE__) #if defined(_WIN32) || defined(__APPLE__) || defined(__linux__)
bool browserHWAccel = ui->browserHWAccel->isChecked(); bool browserHWAccel = ui->browserHWAccel->isChecked();
config_set_bool(App()->GetAppConfig(), "General", "BrowserHWAccel", browserHWAccel); config_set_bool(App()->GetAppConfig(), "General", "BrowserHWAccel", browserHWAccel);
#endif #endif

View file

@ -1124,7 +1124,7 @@ public:
const OBS::Canvas &AddCanvas(const std::string &name, obs_video_info *ovi = nullptr, int flags = 0); const OBS::Canvas &AddCanvas(const std::string &name, obs_video_info *ovi = nullptr, int flags = 0);
public slots: public slots:
bool RemoveCanvas(obs_canvas_t *canvas); bool RemoveCanvas(OBSCanvas canvas);
/* ------------------------------------- /* -------------------------------------
* MARK: - OBSBasic_SceneItems * MARK: - OBSBasic_SceneItems

View file

@ -31,7 +31,7 @@ const OBS::Canvas &OBSBasic::AddCanvas(const std::string &name, obs_video_info *
return it; return it;
} }
bool OBSBasic::RemoveCanvas(obs_canvas_t *canvas) bool OBSBasic::RemoveCanvas(OBSCanvas canvas)
{ {
if (!canvas) if (!canvas)
return false; return false;

View file

@ -334,7 +334,7 @@ void OBSProjector::UpdateProjectorTitle(QString name)
title = QTStr("Projector.Title") + " - " + QTStr("StudioMode.Program"); title = QTStr("Projector.Title") + " - " + QTStr("StudioMode.Program");
break; break;
case ProjectorType::Multiview: case ProjectorType::Multiview:
title = QTStr("Projector.Title") + " - " + QTStr("Multiview"); title = QTStr("Projector.Title") + " - " + QTStr("Projector.Title.Multiview");
break; break;
default: default:
title = name; title = name;

View file

@ -10,8 +10,10 @@
#include <QWindow> #include <QWindow>
#ifdef ENABLE_WAYLAND #ifdef ENABLE_WAYLAND
#include <QApplication> #include <QApplication>
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformnativeinterface.h>
#endif #endif
#endif
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -50,8 +52,12 @@ static bool QTToGSWindow(QWindow *window, gs_window &gswindow)
break; break;
#ifdef ENABLE_WAYLAND #ifdef ENABLE_WAYLAND
case OBS_NIX_PLATFORM_WAYLAND: { case OBS_NIX_PLATFORM_WAYLAND: {
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface(); QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface();
gswindow.display = native->nativeResourceForWindow("surface", window); gswindow.display = native->nativeResourceForWindow("surface", window);
#else
gswindow.display = (void *)window->winId();
#endif
success = gswindow.display != nullptr; success = gswindow.display != nullptr;
break; break;
} }

View file

@ -281,7 +281,7 @@ struct gs_texture *gl_egl_create_texture_from_pixmap(EGLDisplay egl_display, uin
EGLImage image = eglCreateImage(egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, pixmap, pixmap_attrs); EGLImage image = eglCreateImage(egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, pixmap, pixmap_attrs);
if (image == EGL_NO_IMAGE) { if (image == EGL_NO_IMAGE) {
blog(LOG_DEBUG, "Cannot create EGLImage: %s", gl_egl_error_to_string(eglGetError())); blog(LOG_ERROR, "Cannot create EGLImage: %s", gl_egl_error_to_string(eglGetError()));
return NULL; return NULL;
} }

View file

@ -325,22 +325,54 @@ const char *gs_get_device_name(void)
const char *gs_get_driver_version(void) const char *gs_get_driver_version(void)
{ {
return gs_valid("gs_get_driver_version") ? thread_graphics->exports.gpu_get_driver_version() : NULL; graphics_t *graphics = thread_graphics;
if (!gs_valid("gs_get_driver_version"))
return NULL;
if (graphics->exports.gpu_get_driver_version)
return (graphics->exports.gpu_get_driver_version());
else
return NULL;
} }
const char *gs_get_renderer(void) const char *gs_get_renderer(void)
{ {
return gs_valid("gs_get_renderer") ? thread_graphics->exports.gpu_get_renderer() : NULL; graphics_t *graphics = thread_graphics;
if (!gs_valid("gs_get_renderer"))
return NULL;
if (graphics->exports.gpu_get_renderer)
return (graphics->exports.gpu_get_renderer());
else
return NULL;
} }
uint64_t gs_get_gpu_dmem(void) uint64_t gs_get_gpu_dmem(void)
{ {
return gs_valid("gs_get_gpu_dmem") ? thread_graphics->exports.gpu_get_dmem() : 0; graphics_t *graphics = thread_graphics;
if (!gs_valid("gs_get_gpu_dmem"))
return 0;
if (graphics->exports.gpu_get_dmem)
return (graphics->exports.gpu_get_dmem());
else
return 0;
} }
uint64_t gs_get_gpu_smem(void) uint64_t gs_get_gpu_smem(void)
{ {
return gs_valid("gs_get_gpu_smem") ? thread_graphics->exports.gpu_get_smem() : 0; graphics_t *graphics = thread_graphics;
if (!gs_valid("gs_get_gpu_smem"))
return 0;
if (graphics->exports.gpu_get_smem)
return (graphics->exports.gpu_get_smem());
else
return 0;
} }
int gs_get_device_type(void) int gs_get_device_type(void)

View file

@ -65,7 +65,7 @@ static inline void canvas_dosignal_source(const char *signal, obs_canvas_t *canv
calldata_set_ptr(&data, "canvas", canvas); calldata_set_ptr(&data, "canvas", canvas);
calldata_set_ptr(&data, "source", source); calldata_set_ptr(&data, "source", source);
signal_handler_signal(source->context.signals, signal, &data); signal_handler_signal(canvas->context.signals, signal, &data);
} }
/*** Reference Counting ***/ /*** Reference Counting ***/
@ -418,6 +418,11 @@ bool obs_canvas_get_video_info(const obs_canvas_t *canvas, struct obs_video_info
return true; return true;
} }
signal_handler_t *obs_canvas_get_signal_handler(obs_canvas_t *canvas)
{
return canvas->context.signals;
}
void obs_canvas_set_channel(obs_canvas_t *canvas, uint32_t channel, obs_source_t *source) void obs_canvas_set_channel(obs_canvas_t *canvas, uint32_t channel, obs_source_t *source)
{ {
assert(channel < MAX_CHANNELS); assert(channel < MAX_CHANNELS);

View file

@ -34,14 +34,14 @@
* *
* Reset to zero each major version * Reset to zero each major version
*/ */
#define LIBOBS_API_MINOR_VER 0 #define LIBOBS_API_MINOR_VER 1
/* /*
* Increment if backward-compatible bug fix * Increment if backward-compatible bug fix
* *
* Reset to zero each major or minor version * Reset to zero each major or minor version
*/ */
#define LIBOBS_API_PATCH_VER 3 #define LIBOBS_API_PATCH_VER 0
#define MAKE_SEMANTIC_VERSION(major, minor, patch) ((major << 24) | (minor << 16) | patch) #define MAKE_SEMANTIC_VERSION(major, minor, patch) ((major << 24) | (minor << 16) | patch)

View file

@ -2566,6 +2566,9 @@ EXPORT obs_weak_canvas_t *obs_canvas_get_weak_canvas(obs_canvas_t *canvas);
/** Get strong reference from weak reference */ /** Get strong reference from weak reference */
EXPORT obs_canvas_t *obs_weak_canvas_get_canvas(obs_weak_canvas_t *weak); EXPORT obs_canvas_t *obs_weak_canvas_get_canvas(obs_weak_canvas_t *weak);
/** Returns the signal handler for a canvas */
EXPORT signal_handler_t *obs_canvas_get_signal_handler(obs_canvas_t *canvas);
/* Channels */ /* Channels */
/** Sets the source to be used for this canvas. */ /** Sets the source to be used for this canvas. */
EXPORT void obs_canvas_set_channel(obs_canvas_t *canvas, uint32_t channel, obs_source_t *source); EXPORT void obs_canvas_set_channel(obs_canvas_t *canvas, uint32_t channel, obs_source_t *source);

View file

@ -24,6 +24,8 @@
#include "bmem.h" #include "bmem.h"
#include "pipe.h" #include "pipe.h"
extern char **environ;
struct os_process_pipe { struct os_process_pipe {
bool read_pipe; bool read_pipe;
int pid; int pid;
@ -88,7 +90,7 @@ os_process_pipe_t *os_process_pipe_create_internal(const char *bin, char **argv,
posix_spawn_file_actions_adddup2(&file_actions, errfds[1], STDERR_FILENO); posix_spawn_file_actions_adddup2(&file_actions, errfds[1], STDERR_FILENO);
int pid; int pid;
int ret = posix_spawn(&pid, bin, &file_actions, NULL, (char *const *)argv, NULL); int ret = posix_spawn(&pid, bin, &file_actions, NULL, (char *const *)argv, environ);
posix_spawn_file_actions_destroy(&file_actions); posix_spawn_file_actions_destroy(&file_actions);

View file

@ -468,6 +468,7 @@ static int window_rating(HWND window, enum window_priority priority, const char
static const char *generic_class_substrings[] = { static const char *generic_class_substrings[] = {
"Chrome", "Chrome",
"SDL_app",
NULL, NULL,
}; };

View file

@ -10,7 +10,7 @@ endif()
set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_ENABLED "Plugin Support") set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_ENABLED "Plugin Support")
macro(check_obs_browser) macro(check_obs_browser)
if((OS_WINDOWS AND CMAKE_VS_PLATFORM_NAME MATCHES "(Win32|x64)") OR OS_MACOS OR OS_LINUX) if((OS_WINDOWS AND CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)") OR OS_MACOS OR OS_LINUX)
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/obs-browser/CMakeLists.txt") if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/obs-browser/CMakeLists.txt")
message(FATAL_ERROR "Required submodule 'obs-browser' not available.") message(FATAL_ERROR "Required submodule 'obs-browser' not available.")
else() else()

View file

@ -188,7 +188,7 @@ HRESULT HDRVideoFrame::GetFloat(BMDDeckLinkFrameMetadataID metadataID, double *v
break; break;
case bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance: case bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance:
*value = 0.00001; *value = 0.0001;
break; break;
case bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel: case bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel:

View file

@ -248,6 +248,11 @@ static void *v4l2_thread(void *vptr)
blog(LOG_DEBUG, "%s: ts: %06ld buf id #%d, flags 0x%08X, seq #%d, len %d, used %d", data->device_id, blog(LOG_DEBUG, "%s: ts: %06ld buf id #%d, flags 0x%08X, seq #%d, len %d, used %d", data->device_id,
buf.timestamp.tv_usec, buf.index, buf.flags, buf.sequence, buf.length, buf.bytesused); buf.timestamp.tv_usec, buf.index, buf.flags, buf.sequence, buf.length, buf.bytesused);
if (buf.flags & V4L2_BUF_FLAG_ERROR) {
blog(LOG_DEBUG, "skipping decoding of buffer with recoverable error-flag set");
goto continue_queue_buffer;
}
out.timestamp = timeval2ns(buf.timestamp); out.timestamp = timeval2ns(buf.timestamp);
if (!frames) if (!frames)
first_ts = out.timestamp; first_ts = out.timestamp;
@ -266,6 +271,7 @@ static void *v4l2_thread(void *vptr)
} }
obs_source_output_video(data->source, &out); obs_source_output_video(data->source, &out);
continue_queue_buffer:
if (v4l2_ioctl(data->dev, VIDIOC_QBUF, &buf) < 0) { if (v4l2_ioctl(data->dev, VIDIOC_QBUF, &buf) < 0) {
blog(LOG_ERROR, "%s: failed to enqueue buffer", data->device_id); blog(LOG_ERROR, "%s: failed to enqueue buffer", data->device_id);
break; break;

@ -1 +1 @@
Subproject commit b56fd78936761891475458447c1cc9058bb9c2d4 Subproject commit 5ee805695d337cbea4180fd25e5b86bfff4af33b

View file

@ -307,7 +307,7 @@ static int32_t last_time = 0;
static void flv_video(struct serializer *s, int32_t dts_offset, struct encoder_packet *packet, bool is_header) static void flv_video(struct serializer *s, int32_t dts_offset, struct encoder_packet *packet, bool is_header)
{ {
int64_t offset = packet->pts - packet->dts; int32_t ct_offset_ms = get_ms_time(packet, packet->pts) - get_ms_time(packet, packet->dts);
int32_t time_ms = get_ms_time(packet, packet->dts) - dts_offset; int32_t time_ms = get_ms_time(packet, packet->dts) - dts_offset;
if (!packet->data || !packet->size) if (!packet->data || !packet->size)
@ -332,7 +332,7 @@ static void flv_video(struct serializer *s, int32_t dts_offset, struct encoder_p
/* these are the 5 extra bytes mentioned above */ /* these are the 5 extra bytes mentioned above */
s_w8(s, packet->keyframe ? 0x17 : 0x27); s_w8(s, packet->keyframe ? 0x17 : 0x27);
s_w8(s, is_header ? 0 : 1); s_w8(s, is_header ? 0 : 1);
s_wb24(s, get_ms_time(packet, offset)); s_wb24(s, ct_offset_ms);
s_write(s, packet->data, packet->size); s_write(s, packet->data, packet->size);
write_previous_tag_size(s); write_previous_tag_size(s);
@ -486,7 +486,8 @@ void flv_packet_ex(struct encoder_packet *packet, enum video_id_t codec_id, int3
// H.264/HEVC composition time offset // H.264/HEVC composition time offset
if ((codec_id == CODEC_H264 || codec_id == CODEC_HEVC) && type == PACKETTYPE_FRAMES) { if ((codec_id == CODEC_H264 || codec_id == CODEC_HEVC) && type == PACKETTYPE_FRAMES) {
s_wb24(&s, get_ms_time(packet, packet->pts - packet->dts)); int32_t ct_offset_ms = get_ms_time(packet, packet->pts) - get_ms_time(packet, packet->dts);
s_wb24(&s, ct_offset_ms);
} }
// packet data // packet data

@ -1 +1 @@
Subproject commit c542622d7b6d41ce5875f54efdab1d4ac2967ef4 Subproject commit 79cd0c729e46cae785d2035d9d7ffe1379adbe7e

View file

@ -7,6 +7,9 @@ static uint8_t *get_bitmap_data(HBITMAP hbmp, BITMAP *bmp)
if (GetObject(hbmp, sizeof(*bmp), bmp) != 0) { if (GetObject(hbmp, sizeof(*bmp), bmp) != 0) {
uint8_t *output; uint8_t *output;
unsigned int size = bmp->bmHeight * bmp->bmWidthBytes; unsigned int size = bmp->bmHeight * bmp->bmWidthBytes;
if (!size) {
return NULL;
}
output = bmalloc(size); output = bmalloc(size);
GetBitmapBits(hbmp, size, output); GetBitmapBits(hbmp, size, output);
@ -99,6 +102,9 @@ static inline uint8_t *copy_from_mask(ICONINFO *ii, uint32_t *width, uint32_t *h
bmp.bmHeight /= 2; bmp.bmHeight /= 2;
pixels = bmp.bmHeight * bmp.bmWidth; pixels = bmp.bmHeight * bmp.bmWidth;
if (!pixels) {
return NULL;
}
output = bzalloc(pixels * 4); output = bzalloc(pixels * 4);
bottom = bmp.bmWidthBytes * bmp.bmHeight; bottom = bmp.bmWidthBytes * bmp.bmHeight;